IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Affichage d'une mosaïque d'images


Sujet :

Qt

  1. #1
    Candidat au Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Octobre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 9
    Points : 2
    Points
    2
    Par défaut Affichage d'une mosaïque d'images
    Bonjour.
    Je suis en train de débuter dans Qt venant de visual studio.
    Je suis un peu honteux de demander de l'aide pour un truc qui doit être super basique mais cela fait 3 jours que je cherche en vain à reproduire ce qui était ultra facile en V studio.
    Je veux composer une image dans un QGraphicView à l'aide d'une mosaique d'images PNG. Ces images ont la taille requise et n'ont pas besoin de subir un quelconque traitement. Je n'arrive pas à placer les images ailleurs qu'en coordonnées 0,0 de la scene.
    QGraphicsScene::addPixmap(image) n'accepte pas de coordonnées d'insertion comme son équivalent de Visual studio.
    Je suppose donc qu'il faut utiliser quelque chose du genre Qpainter::fillRect(image) mais ensuite QGraphicsScene::addRect(QRect) n'affiche que le rectangle aux bonnes coordonnées mais sans son contenu supposé.
    J'ai aussi essayé d'utiliser QPainter::(target_QRect,image,source_QRect) qui, suivi de QGraphicsScene::addRect(QRect) me donne le même résultat.
    Voici le bout de code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        scene2 = new QGraphicsScene;
        ui->Plan2DGV->setScene(scene2);
        scene2->setSceneRect(0,0,350,350);
        QRectF target (20,20,90,90); // même résultat avec QRect
        QPixmap image("D:/doc/doc c++/fleche-haut.png");
        peintre = new QPainter();
        peintre->fillRect(target,image);
        scene2->addRect(target);
    Je vous remercie par avance. J'espère avoir été assez précis.

    JDEL416

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Citation Envoyé par JDEL416 Voir le message
    QGraphicsScene::addPixmap(image) n'accepte pas de coordonnées d'insertion comme son équivalent de Visual studio.
    Cette fonction non, mais l'instance de type QGraphicsPixmapItem * (et la classe QGraphicsItem dont elle hérite) qu'elle retourne possède tout ce qu'il faut

  3. #3
    Candidat au Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Octobre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 9
    Points : 2
    Points
    2
    Par défaut Affichage d'une mosaique d'images
    Merci beaucoup pour votre aide pour m'avoir orienté. J'aurais du y penser.
    Bon je ne vois pas quand même le moyen de charger l'image dans la scène directement au bon endroit. Il semble qu'il faille la charger en 0,0 et ensuite la déplacer. Mais on ne va pas chipoter.

    J'ai tapé cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        scene = new QGraphicsScene();
        ui->Plan2DGV->setScene(scene);
        scene->setSceneRect(0,0,350,350);
        QGraphicsPixmapItem *fleche;
        QPixmap image("D:/doc/doc c++/fleche_haut.png");
        fleche = scene->addPixmap(image); //puisqu'il n'y a pas de QGraphicsScene::addGraphicsPixmapItem(image)
        fleche->setOffset(100,100);
    En fait, ça n'a pas l'air de marcher. Je ne vois pas bien pourquoi parce que :

    Ce qui suit, qui ressemble étrangement, fonctionne parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        scene2 = new QGraphicsScene;
        ui->Plan2DGV->setScene(scene2);
        scene2->setSceneRect(0,0,350,350);
        QGraphicsItem *fleche_haut;
        QPixmap image2("D:/doc/doc c++/fleche-haut.png");
        fleche_haut = scene2->addPixmap(image2);
     
        fleche_haut->setPos(100,150);
        fleche_haut->setScale(4);
        fleche_haut->setRotation(30);
    Donc tout va bien.
    Si je peux abuser , j'ai des questions :
    1) Une fois que j'ai fait un addPixmap, l'image appartient à la scène et sera détruite avec son pointeur en même temps que la scène ou dois-je détruire le pointeur ?
    2) Si je crée une nouvelle scène dans le même QGraphicsview, la scène précédente est-elle détruite automatiquement avec tout ce qu'elle contient ou dois-je le faire ?

    Merci encore.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par JDEL416 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        fleche = scene->addPixmap(image); //puisqu'il n'y a pas de QGraphicsScene::addGraphicsPixmapItem(image)
    Mais il existe QGraphicsScene::addItem(QGraphicsItem *item). Tu peux créer un QGraphicsPixmapItem *, le paramétrer comme bon te semble, puis l'ajouter avec.

    Citation Envoyé par JDEL416 Voir le message
    1) Une fois que j'ai fait un addPixmap, l'image appartient à la scène et sera détruite avec son pointeur en même temps que la scène ou dois-je détruire le pointeur ?
    C'est la scène qui s'occupe de la détruire, comme tout QGraphicsItem * ajouté avec addItem() :
    This scene takes ownership of the item.
    Citation Envoyé par JDEL416 Voir le message
    2) Si je crée une nouvelle scène dans le même QGraphicsview, la scène précédente est-elle détruite automatiquement avec tout ce qu'elle contient ou dois-je le faire ?
    Comme il est dit dans QGraphicsView::setScene :
    The view does not take ownership of scene.
    Donc changer de scène ne détruira pas la précédente.

  5. #5
    Candidat au Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Octobre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 9
    Points : 2
    Points
    2
    Par défaut Affichage d'une mosaique d'images
    Bonjour.
    Merci de passer du temps avec mon problème. Aider un débutant n'est pas très stimulant. Désolé.
    1) GraphicsScene::addItem() ne prend pas plus d'argument de positionnement que addPixmap.
    2) J'ai exploré QGraphicsPixmapItem. Il y a bien une fonction setPixmap mais elle ne prend pas d'argument de positionnement non plus.
    Par contre QGraphicsPixmapItem::setOffset(x,y) existe.
    J'ai donc écrit le code suivant.
    Code Qt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    scene = new QGraphicsScene();
        ui->Plan2DGV->setScene(scene);
        scene->setSceneRect(0,0,350,350);
        QPixmap image("D:/doc/doc c++/fleche_haut.png");
        QGraphicsPixmapItem fleche;
        fleche.setPixmap(image);
        fleche.setOffset(100,100);
        scene->addItem(fleche);
    Est-ce ce que j'étais supposé faire ?
    Le compilateur me dit à propos de la dernière ligne du code :" impossible de convertir l'argument 1 de QGraphicPixmapItem en QGraphicsItem"
    Le code suivant ne fait pas mieux : Les modifications par rapport au code précédent sont en rouge.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    scene = new QGraphicsScene();
        ui->Plan2DGV->setScene(scene);
        scene->setSceneRect(0,0,350,350);
        QPixmap image("D:/doc/doc c++/fleche_haut.png");
        QGraphicsPixmapItem *fleche;
        fleche->setPixmap(image);
        fleche->setOffset(100,100);
        scene->addItem(fleche);
    Le compilateur ne bronche pas mais le RUN plante lors du clic sur le bouton lançant ce bout de code. Message erreur ci-dessous:
    64bit HCBT_CREATEWND event startSetProcessDpiAwareness(2) failed: COM error 0xffffffff80070005 (Unknown error 0x0ffffffff80070005), using 2
    64bit HCBT_CREATEWND event start64bit HCBT_CREATEWND event start64bit HCBT_CREATEWND event startWindow 64 bit Class Name - [Qt5QWindowIcon]64 bit Window Class Name - [Qt5QWindowIcon]64 bit Hook() - HCBT_CREATEWND child/popup window64bit HCBT_CREATEWND event start HCBT_SETFOCUS 64 Before
    HCBT_SETFOCUS 64 After
    64bit HCBT_CREATEWND event start64bit HCBT_CREATEWND event startThe program has unexpectedly finished.
    D:\doc\doc c++\build-laby1-Desktop_Qt_5_6_1_MSVC2015_64bit-Debug\debug\laby1.exe crashed.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Aïe aïe aïe, un bon cours sur les pointeurs et l'héritage s'impose

    Mon passage
    Citation Envoyé par Winjerome
    (et la classe QGraphicsItem dont elle hérite)
    n'était pas anodin. La classe QGraphicsPixmapItem héritant de la classe QGraphicsItem :
    • elle possède de ce fait toutes les fonctions membres de QGraphicsItem, dont la fonction setPos() qui est bien celle que tu recherches ;
    • elle peut très bien être passée là où on attend une QGraphicsItem, comme le fait GraphicsScene::addItem(). (principe du LSP).

    Dans l'idée, tu as deux solutions :
    • Soit récupérer la sortie de addPixmap() qui va créer puis ajouter à la scène l'objet de type QGraphicsPixmapItem *, puis régler sa position :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      QGraphicsPixmapItem * upArrowItem = scene->addPixmap(QPixmap{"D:/doc/doc c++/fleche_haut.png"});
      upArrowItem->setPos(100, 100);
    • Soit créer toi-même l'objet de type QGraphicsPixmapItem, régler sa position, puis l'ajouter à la scène :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      QGraphicsPixmapItem * upArrowItem = new QGraphicsPixmapItem{QPixmap{"D:/doc/doc c++/fleche_haut.png"}};
      upArrowItem->setPos(100, 100);
      scene->addItem(upArrowItem);


    Concernant tes essais :
    Citation Envoyé par JDEL416 Voir le message
    Code Qt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        QGraphicsPixmapItem fleche;
        fleche.setPixmap(image);
        fleche.setOffset(100,100);
        scene->addItem(fleche);
    Là, tu crées un objet local qui sera détruit à la fin du bloc { ... } qui le contient.
    Et il faut bien faire la différence entre un pointeur de type QGraphicsPixmapItem * et un tel objet de type QGraphicsPixmapItem. La fonction addItem() attend un pointeur. Autant la conversion QGraphicsPixmapItem * vers QGraphicsItem * est parfaitement valide grâce à l'héritage, autant QGraphicsPixmapItem vers QGraphicsItem * ne le sera pas.
    Tu peux peut-être penser que tu aurais pu passer l'adresse de cet objet, mais l'objet ayant été détruit à la fin du bloc, la scène aurait quand même continué à manipuler cet objet « fantome » à cette adresse et aurait même au final cherché à le détruire une seconde fois. Là cela aurait été la porte ouverte au comportement indéfini (undefined behavior « UB » en anglais), avec un très probable crash en perspective.

    Citation Envoyé par JDEL416 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        QGraphicsPixmapItem *fleche;
        fleche->setPixmap(image);
        fleche->setOffset(100,100);
        scene->addItem(fleche);
    Là c'était mieux, mais tu n'as pas pensé à allouer de la mémoire avec new pour le pointeur. Ce qu'il fait qu'il pointait sur une adresse totalement aléatoire et certainement pas utilisable : encore un UB dont tu as pu voir les effets.

  7. #7
    Candidat au Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Octobre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 9
    Points : 2
    Points
    2
    Par défaut Affichage mosaique d'images
    Bonjour.
    J'ai refait des tests et réfléchi à tes commentaires très instructifs.

    Tout d'abord : le code suivant est commun et en tête de tous les tests réalisés :
    Code 0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    scene = new QGraphicsScene();
        ui->Plan2DGV->setScene(scene);
        scene->setSceneRect(0,0,350,350);
    Le premier code qui fonctionne est le suivant :
    code 1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    QGraphicsItem *fleche_haut;
        QPixmap image2("D:/doc/doc c++/fleche-haut.png");
        fleche_haut =scene->addPixmap(image2);
        fleche_haut->setPos(100,100);
    Le code ci-dessus affiche une image avec ou sans pointeur.
    Dans ce cas, l'utilité du pointeur est de pouvoir manipuler l'objet une fois placé dans la scène aux coordonnées (0,0).

    Avec tes conseils (mal suivis sans aucun doute), j'avais donc écrit ceci qui plante le système.
    Et bon, Ok. Je suppose bien qu'il faut de la mémoire pour y mettre une image. Pigé.
    Code 2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    QPixmap image("D:/doc/doc c++/fleche-haut.png");
        QGraphicsPixmapItem *fleche;
        fleche->setPixmap(image);
        fleche->setOffset(100,100);
        scene->addItem(fleche);
    Mais j'avais aussi essayé le code suivant sans en avoir formalisé l'intérêt mais plutôt en me disant: "Si on essayait cela?".
    Cela ne plantait pas mais rien n'était affiché:
    Code 3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    QPixmap image("D:/doc/doc c++/fleche-haut.png");
        fleche = new QGraphicsPixmapItem;
        fleche->setPixmap(image);
        fleche->setOffset(100,100);
        scene->addItem(fleche);
    J'ai, en suivant tes conseils essayé les deux codes suivants plus compacts:
    Code 4)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    upArrowItem = new QGraphicsPixmapItem(QPixmap("D:/doc/doc c++/fleche_haut.png"));
       upArrowItem->setPos(100, 100);
       scene->addItem(upArrowItem);
    Dans le cas ci-dessus, c'est OK. Il faut allouer de la mémoire pour l'objet graphique qui va manipuler l'image.
    Dans le cas ci-dessous, il n'y a pas besoin d'allouer de la mémoire puisque c'est la scène qui renvoie au pointeur l'adresse d'un composants de la scène qui vient d'être créé.
    Code 5)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    QGraphicsPixmapItem *upArrowItem = scene->addPixmap(QPixmap("D:/doc/doc c++/fleche_haut.png"));
        upArrowItem->setPos(100, 100);

    Le dernier problème est de comprendre pourquoi, l'image apparait (code1) avec scene->addPixmap(QPixmap) et que rien ne s'affiche (Code 2-3-4-5) avec scene->addItem(QgraphicsPixmaxItem).
    J'ai essayé d'ajouter : upArrowItem->setVisible(true) que j'ai trouvé dans QGraphicsItem (l'héritage auquel je n'avais pas pensé hier. Hoops!) sans résultat.
    A part cela, c'est vraiment très très sympa de m'aider. Merci.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Pour le 2) c'est tout à fait normal : il manque l'initialisation du pointeur.
    Par contre, et je viens de tester, les codes 3), 4) et 5) devraient fonctionner

  9. #9
    Candidat au Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    Octobre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 9
    Points : 2
    Points
    2
    Par défaut affichage mosaique d'image.
    Désolé ; j'aurais déjà dû ajouter un commentaire car j'ai finalement trouvé une solution.
    C'est le code que tu m'as donné mais j'ai un peu décompacté en ajoutant un pixmap intermédiaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    m_ui->Plan2DGV->setScene(m_scene);
        m_scene->setSceneRect(0,0,360,360);
        QPixmap image("D:/doc/doc c++/fleche_haut.png");
        fleche=new QGraphicsPixmapItem(image);
        fleche->setPos(5,5);
        m_scene->addItem(fleche);
    et cela fonctionne parfaitement. Cela semble tout à fait curieux d'avoir résolu le problème de cette façon.

    Merci beaucoup. Comme toujours on apprend beaucoup plus de ses erreurs que de ses réussites.

Discussions similaires

  1. Lecture et affichage d'une séquence d'images
    Par Nates dans le forum OpenCV
    Réponses: 14
    Dernier message: 18/05/2011, 14h11
  2. affichage d'une galerie d'images
    Par boubeuch dans le forum Langage
    Réponses: 2
    Dernier message: 22/04/2010, 12h01
  3. Affichage d'une series d'image en GTK
    Par majed_la7 dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 13/11/2007, 17h10
  4. [Lazarus] Affichage d'une grille d'images
    Par Brupio dans le forum Lazarus
    Réponses: 1
    Dernier message: 01/04/2007, 15h42
  5. Affichage d'une très grande image
    Par Exca dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 26/12/2006, 20h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo