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 Objet heritant de QObject et QGraphicsITem [2D/3D]


Sujet :

Qt

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 16
    Points
    16
    Par défaut Affichage Objet heritant de QObject et QGraphicsITem
    bonjour,

    j'ai fait un bout de code avec un pote qui affiche des objets 2D.
    pour cela on a :
    - une fenêtre contenant une scène.
    elle récupère les images d'un objet pour les afficher.

    - une classe abstraite GraphicsObject : public QObject, public QGraphicsItem.
    qui prend en paramètre une QListe<Qpixmap*> et crée un tableau de QGraphicsPixmapItem

    - des classes Magiciennes, Nuages... héritants de GraphicsObject

    -un PixSender, qui stocke toutes les pixmap utiles à l'application dans des tableaux de QPixmap et les renvoie à un objet GraphicsObject lors de sa création.

    voilà pour la petite histoire.
    les sources ici : http://leszenfoires.fr/jdr

    mais puisque mes objets graphiques héritent de QGraphicsItem, ne serait-il pas mieux d'ajouter directement un de ces objets à la scene ?
    de faire scene->additem(magicienne); au lieu de scene->addPixmap(magicienne->getpixmap());
    (magicienne étant un objet graphique)

    ça ne renvoie pas d'erreur mais évidemment ça n'affiche rien.
    je ne défini aucun parent dans le programme.
    ça pourrait venir de là ?
    ou peut être faire un truc du style magicienne->setPixmap(pixmapcourante)
    (mais un QGraphicsItem n'a pas de membre setPixmap() )

    enfin bref je ne trouve pas comment faire.
    mon but final étant de pouvoir récupérer les events souris et clavier sur les objets.

    une petite idée ?

    GraphicsObject.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    /*
    	Classe Abstraite pour tous les objets graphiques
    	réimplémenter initpixList qui sert à afficher l'objet
     
    */
    #ifndef HEADER_GRAPHICSOBJECT
    #define HEADER_GRAPHICSOBJECT
    #include <QGraphicsPixmapItem>
    #include <iostream>
    #include <QMouseEvent>
    #include "PixSender.h"
    #include <QPainter>
     
    typedef struct M_Current{
            M_Current(int a,QString s)
            {
              image=a;
              state=s;
            }
            int image;
            QString state;
    }MCurrent; //cette structure permet de situer à quelle image et dans quelle position se trouve un personnage("stand", "walk" ...)
     
    class GraphicsObject :  public QObject, public QGraphicsItem
    {
        Q_OBJECT
        public:
            GraphicsObject(QList<QPixmap*> pixObject,QPointF position = QPointF(300,200), MCurrent current = MCurrent(0,"stand")) : mCurrentImage(current){
            setPos(position);  //defini la position d e l'objet
            mArea = pixObject.at(0)->size(); //récupère la taille de la premiere image pour boundingRect() et paint()
     
             };
             virtual ~GraphicsObject(){};
             virtual void initPixList(QList<QPixmap*> pixObject,QPointF position = QPointF(300,200)) = 0;
             void standAnimation(int max);
             MCurrent getCurrentImage();
             QGraphicsPixmapItem* getPixmap(int i, QString state);
             QRectF boundingRect() const;
             void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    //	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
        signals:
            void OnObject();
     
        protected :
            QList <QGraphicsPixmapItem*> mStandPixmap; // tableau pour la position "stand"
            QList <QGraphicsPixmapItem*> mWalkPixmap; // tableau pour la position "walk"
            MCurrent mCurrentImage;
            QSize mArea;
            virtual void mousePressEvent(QGraphicsSceneHoverEvent * event);
     
    };
     
     
     
    #endif
    GraphicsObject.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    #include "GraphicsObject.h"
    #include <iostream>
    using namespace std;
     
     
    void GraphicsObject :: standAnimation(int max)
    {
        mStandPixmap.at(mCurrentImage.image)->setVisible(0);
        if (mCurrentImage.image==max-1) mCurrentImage.image = 0;
            else mCurrentImage.image ++;
        mStandPixmap.at(mCurrentImage.image)->setVisible(1);
    }
     
    QGraphicsPixmapItem* GraphicsObject :: getPixmap(int i, QString state)
    {
     if (state == "stand") return mStandPixmap.at(i);
     return mWalkPixmap.at(i);
    }
     
     
     
    QRectF GraphicsObject :: boundingRect() const
    {
        return QRectF(pos().x(),pos().y(),mArea.width(),mArea.height());
    }
     
    void GraphicsObject :: paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
    {
        painter->drawRect(boundingRect());
     
    }

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par mrdus Voir le message
    mais puisque mes objets graphiques héritent de QGraphicsItem, ne serait-il pas mieux d'ajouter directement un de ces objets à la scene ?
    si .
    Normalement, il suffit que ton GraphicObject soit l'item parent de tes QPixmapItem.

    Au lieu de GraphicsObject, pourquoi ne pas avoir utilisé qgraphicsobject
    http://qt.developpez.com/doc/latest/...icsobject.html

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour mrdus

    Quelques petites questions :
    - Pourquoi hériter de QObject ?
    - Pourquoi créer une classe qui hérite de QGraphicsItem et qui contient des QGraphicsPixmapItem ?

    Ne peux-tu pas créer une classe PixmapBuilder (par exemple), qui n'hérite pas de QObject ou de QGraphicsItem, et qui aurait le responsabilité de créer les QGraphicsPixmapItem et les envoyer directement à la scène ?

    Pour la gestion des events, il suffit de redéfinir les fonctions virtuelles correspondantes : http://qt.developpez.com/doc/latest/...cted-functions

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par yan Voir le message
    si .
    Normalement, il suffit que ton GraphicObject soit l'item parent de tes QPixmapItem.

    Au lieu de GraphicsObject, pourquoi ne pas avoir utilisé qgraphicsobject
    http://qt.developpez.com/doc/latest/...icsobject.html
    hé ben tout simplement parce qu'elle m'avait échappé
    alors là ...

    ...plus tard...
    je n'ai pas (encore) modifié l'héritage de ma classe GraphicsObject.
    mais ça marche nickel en spécifiant le parent de chaque image.

    en revanche j'ai un problème avec mes fonctions paint() et boundingRect()

    elles m'affichent le rectangle lors de la création d'un objet.
    normal en fait.
    mais ce rectangle se situe un peu n'importe où. et ne correspond pas à l'emplacement réel des objets spécifié lors du new :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Magiciennne* mage = new Magicienne(pixSender->sendList("mage"),QPointF(360,280),MCurrent(rand()%NB_STAND,"stand"));
    (le QPointF (x,y) est la position de départ de l'objet.

    un appel à boundingRect() plus tard m'affiche bien le rectangle à la bonne position autour de la magicienne.(cf capture)
    mais il y a aussi un carré en bas à droite(surement lors de la création).
    et également le carré des nuages.
    déjà je vois pas pourquoi le carré des nuages s'affiche à un endroit et celui de la magicienne ailleurs. (et toujours aux même endroits)
    et je capte pas bien à quoi ça sert d'implémenter paint() si c'est pour enlever la seule ligne qu'elle contient.


    edit : @gbdivers
    je n'avais pas vu ton message.
    j'ai pensé à faire directement une classe qui contient les QGraphicsPixmapItem.
    mais je me suis dit que, pour que 2 personnages identiques soient à des positions différentes à un instant T, il fallait faire 2 tableaux de ces images, puisque ce ne seront pas les mêmes visibles à un instant T. donc un tableau dans chaque objet.
    Images attachées Images attachées  

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Attention, certaines valeurs sont initialisées correctement qu'au premier display et non dans le constructeur, comme boundingRect
    Si tu créé un item à partir du boundingRect dans le constructeur, ce ne sera pas la bonne valeur.
    [edit]
    il me semble qu'il y as une fonction pour l'obligé à calculer ces valeurs, mais je ne me rappel plus du nom.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    @ gbdivers : je t'ai répondu dans mon message précédent.

    j'avais compris que la méthode paint servait à connaitre la position de l'objet pour par exemple utiliser les events.
    mais si je la rappelle pas après la construction alors elle n'est pas mise à jour c'est bien ça ?

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par mrdus Voir le message
    j'avais compris que la méthode paint servait à connaitre la position de l'objet pour par exemple utiliser les events.
    Comme son nom l'indique, elle sert à peindre (dessiner) l'item
    c'est quoi ton problème?

  8. #8
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    En fait, je ne suis pas sur que tu utilises la bonne approche.

    A priori, tu peux utiliser directement les QGraphicsView, QGraphicsScene et les QGraphicsPixmapItem (pour les objets inanimé) et créer une classe pour les objets animés, dérivé de QGraphicsPixmapItem et définissant le comportement de l'objet (en redéfinissant les events).

    en pseudo code, ça donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class AnimatedObject : public QGraphicsItem
    {
        virtual void keyPressEvent ( QKeyEvent * event )
        {
            // en fonction de la touche, on déplace l'item avec moveBy()
            // puis on fait un update()
        }
     
        virtual void advance( )
        {
            // on avance les objets non controlés par le joueur
        }
    };
     
    main()
    {
        // on initialise la scene et la vue
     
        foreach // pour chaque objet inanimé que l'on veut créer
        {
            // on crée un AnimatedObject. On position avec setPos() 
            // et on définit la pixmap avec setPixmap()
        }
     
        foreach // pour chaque objet animé que l'on veut créer
        {
            // on crée un QGraphicsPixmapItem. On position avec setPos() 
            // et on définit la pixmap avec setPixmap()
        }
     
        // on crée un timer qui appelle la fonction QGraphicsScene::advance()
        // pour animer la scène
    }
    Fini !

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    salut,
    d'abord merci pour vos réponses : elles ont été utiles
    j'ai fait une petite pose (de lambris) et une petite pause de programmation.
    je commençais à me décourager.
    ça va mieux

    on a repensé un peu le code : il est plus simple.
    les objets usuels comme des nuages qui ont leur vie propre sont maintenant instanciés grâce à la classe UsualObject, et on les range tous dans un tableau.
    ça ressemble un peu à ton schéma, gbdivers.

    bref.
    maintenant on aimerait bien la faire bouger cette pauvre magicienne.
    si le MousePressEvent ne pose aucun souci, le ReleaseEvent en revanche...ne fonctionne pas du tout. ni directement sur les objets, ni sur la fenêtre principale.

    l'autre probleme qui me tire plus souci, c'est toujours l'histoire de boudingREct et paint() qui ne s'initialisent pas correctement.
    les cadres définis par paint sont à côté de mes objets ou ailleurs en dehors de la scene, ça dépend (par contre c'est toujours au mêmes endroits)

    edit : j'oubliais : les sources ici
    Images attachées Images attachées  

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    pour le mouseReleaseEvent, il fallait juste ajouter la méthode grabMouse de QWidget et ça fonctionne nickel.
    je marque le sujet résolu, merci de votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage objets kml distincts dans API Google Earth
    Par Bruno REDUREAU dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/03/2009, 11h43
  2. [POO] Fonction Affichage OBjet Javascript!
    Par lekunfry dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 20/07/2007, 06h28
  3. Tester si un objet herite d'u autre
    Par adilou1981 dans le forum Langage
    Réponses: 1
    Dernier message: 23/11/2006, 10h51
  4. Réponses: 13
    Dernier message: 01/09/2005, 15h09
  5. Réponses: 3
    Dernier message: 09/02/2003, 01h09

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