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 :

Signal selectionChanged() d'un QGraphicsScene


Sujet :

Qt

  1. #1
    Candidat au Club
    Inscrit en
    Avril 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 7
    Points : 4
    Points
    4
    Par défaut Signal selectionChanged() d'un QGraphicsScene
    Bonjour,

    Pour faire simple, je fais un éditeur de map et je souhaite que le curseur de la souris prenne la forme de la tuile séléctionnée dans le tileset lorsque je survole la map.

    Pour ça mon MainWindow (qui contient ma map et mon tileset) connecte un signal de ma classe Tileset à un slot de ma classe Map. Le signal du tileset est lui même émit par un slot appelé grâce au signale de la classe QGraphicsScene; selectionChanged().

    Mon problème est que le signal n'est jamais émit, tout du moins MON signal. Pour selectionChanged() je ne sais pas si il est émit.

    Parce que le code vaut mieux que de longs discours... Le voici :

    main.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
     
    #include <QtGui/QApplication>
    #include "mainwindow.h"
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();    
        return a.exec();
    }
    MainWindow.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
     
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QtGui>
    #include "ui_mainwindow.h"
    #include <iostream>
    #include "tileset.h"
    #include "map.h"
     
    class MainWindow : public QMainWindow, private Ui::MainWindow
    {
        Q_OBJECT
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
        void setTileset();
     
    private:
        Tileset *tileset;
        Map *carte;
     
    public slots:
        void on_boutonSelectTileset_clicked();
    };
     
    #endif // MAINWINDOW_H
    MainWindow.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
     
    #include "mainwindow.h"
     
    using namespace std;
     
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent)
    {
        setupUi(this);
        tileset=new Tileset();
        layoutTileset->addWidget(tileset);
        carte=new Map();
        layoutMap->addWidget(carte);
     
        QObject::connect(tileset, SIGNAL(newSelection(QPixmap)), carte, SLOT(setCurseur(QPixmap)));
    }
     
    MainWindow::~MainWindow()
    {
        delete tileset;
        delete carte;
    }
     
    void MainWindow::on_boutonSelectTileset_clicked()
    {
        tilesetSelected->setText(tileset->changeTileset());
        Dock_tileset->setMinimumWidth(tileset->getTilesetWidth()+70);
        Dock_tileset->setMaximumWidth(tileset->getTilesetWidth()+70);
    }
    Tileset.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
     
    #ifndef TILESET_H
    #define TILESET_H
     
    #include <QtGui>
    #include "tuile.h"
    #include <iostream>
     
    class Tileset : public QGraphicsView
    {
        Q_OBJECT
    public:
        Tileset(QWidget *parent = 0);
        ~Tileset();
        void setTileset();
        int getTilesetWidth();
        QString changeTileset();
        void deleteTileset();
        void decoupeTuile();
        void update();
     
    private:
        QGraphicsScene *m_sceneTileset;
        QPixmap m_tileset;
        QString m_adresseImage;
        QVector<Tuile*> m_tuiles;
     
    signals:
        void newSelection(QPixmap);
     
    public slots:
        void selectionChangee();
     
    };
     
    #endif // TILESET_H
    Tileset.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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
     
    #include "tileset.h"
     
    Tileset::Tileset(QWidget *parent) :
        QGraphicsView(parent)
    {
        m_adresseImage="";
        m_sceneTileset=new QGraphicsScene();
        setScene(m_sceneTileset);
        QObject::connect(m_sceneTileset, SIGNAL(selectionChanged()), this, SLOT(selectionChangee()));
    }
     
    Tileset::~Tileset()
    {
        delete m_sceneTileset;
    }
     
    //Retourne la largeur du tileset (afin par exemple de redimentionner le dock du MainWindow)
    int Tileset::getTilesetWidth()
    {
        return m_tileset.width();
    }
     
    //Charge une image dans le tileset
    //Appelle la méthode decoupeTuile
    void Tileset::setTileset()
    {
        m_tileset.load(m_adresseImage);
        decoupeTuile();
    }
     
    //Remplit le vector de tuiles en créant des objets de type Tuile avec les parties du tileset
    //Appelle la méthode Update
    void Tileset::decoupeTuile()
    {
        m_tuiles.clear();
        int i(0), j(0);
        for(j=0;j<m_tileset.height()/32;j++)
        {
            for(i=0;i<m_tileset.width()/32;i++)
            {
                m_tuiles.push_back(new Tuile(&m_tileset, i*32, j*32));
            }
        }
        update();
    }
     
    //Ajoute les objets de type Tuile au sceneTileset et les positionne
    //Applique la scene au viewTileset et l'affiche
    void Tileset::update()
    {
        if(m_sceneTileset!=0)
        {
            delete m_sceneTileset;
            m_sceneTileset=new QGraphicsScene();
        }
     
        int i(0), j(0), t(m_tileset.height()/32*m_tileset.width()/32-1);
        for(j=m_tileset.height()/32;j>0;j--)
        {
            for(i=m_tileset.width()/32;i>0;i--)
            {
                m_sceneTileset->addItem(m_tuiles[t]);
                m_tuiles[t]->setPos(i*32, j*32);
                t--;
            }
        }
        setScene(m_sceneTileset);
        show();
    }
     
    //Ouvre une boite de dialogue pour choisir le nouveau tileset
    //Appelle la methode setScene()
    QString Tileset::changeTileset()
    {
        while((m_adresseImage = QFileDialog::getOpenFileName(this, "Ouvrir un tileset", QString(), "Images (*.png *.gif *.jpg *.jpeg)")) == "")
        {
            QMessageBox::warning(this, "Tileset incorrect", "Veuillez sélectionner un tileset valide");
        }
        deleteTileset();
        setTileset();
        return m_adresseImage;
    }
     
    void Tileset::deleteTileset()
    {
        int i = 0, j = 0, t=0;
        for(j=0;j<m_tileset.height()/32;j++)
        {
            for(i=0;i<m_tileset.width()/32;i++)
            {
                m_sceneTileset->removeItem(m_tuiles[t]);
                t++;
            }
        }
    }
     
     
     
    //////////////////////////////////////
    ///////////////SLOTS//////////////////
    //////////////////////////////////////
    void Tileset::selectionChangee()
    {
        for(int i=0; i<=(m_tileset.height()/32*m_tileset.width()/32-1);i++)
        {
            if(m_tuiles[i]->isSelected())
            {
                emit newSelection(m_tuiles[i]->getPixmapTuile());
     
            }
        }
        qDebug() << "signal émit";
    }
    Map.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
     
    #ifndef MAP_H
    #define MAP_H
     
    #include <QtGui>
    #include"Tileset.h"
     
    class Map : public QGraphicsView
    {
        Q_OBJECT
    public:
        Map(QWidget *parent = 0, Tileset *tileset=0);
        ~Map();
     
    private:
        QCursor *m_curseur;
        Tileset *m_tileset;
        QGraphicsScene *m_sceneMap;
     
    public slots:
        void setCurseur(QPixmap tilePixmap);
     
    };
     
    #endif // MAP_H
    Map.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
     
    #include "map.h"
     
    Map::Map(QWidget *parent, Tileset *tileset) :
        QGraphicsView(parent)
    {
        m_tileset=tileset;
        m_sceneMap=new QGraphicsScene();
        m_curseur=new QCursor(Qt::PointingHandCursor);
        setScene(m_sceneMap);
        setCursor(*m_curseur);
    }
     
    Map::~Map()
    {
     
    }
     
    void Map::setCurseur(QPixmap tilePixmap)
    {
        if(m_curseur)
        {
            delete m_curseur;
        }
        m_curseur=new QCursor(tilePixmap);
        setCursor(*m_curseur);
     
        qDebug() << "setCurseur";
    }
    Tuile.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
     
    #ifndef TUILE_H
    #define TUILE_H
     
    #include <QtGui>
     
    class Tuile : public QGraphicsPixmapItem
    {
    public :
        Tuile(QPixmap *tileset=0, int x=0, int y=0);
        ~Tuile();
        QPixmap getPixmapTuile();
     
    private :
        QSize m_sizeTile;
        QPixmap m_tuile;
        int m_id;
        QString m_Tileset;
        int m_x;
        int m_y;
    };
     
    #endif
    Tuile.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
     
    #include "Tuile.h"
     
    Tuile::Tuile(QPixmap *tileset, int x, int y)
    {
        m_sizeTile.setWidth(32);
        m_sizeTile.setHeight(32);
        m_x=x;
        m_y=y;
        setPixmap(tileset->copy(m_x, m_y, m_sizeTile.width(), m_sizeTile.height()));
        setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
        setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
    }
     
    Tuile::~Tuile()
    {
     
    }
     
    QPixmap Tuile::getPixmapTuile()
    {
        return pixmap();
    }
    Voilà, pouvez vous me dire ce qui cloche? Peut être que je ne fais pas ce qu'il faut avec les signaux et les slots... Help!

    Merci à vous

  2. #2
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    J'aurais tendance à dire qu'il manque un setInteractive(true) sur le QGraphicsView. Après, il est également possible que les réimplémentations de QGraphicsItem n'implémentent pas toutes les fonctions et qu'elles ne soient pas sélectionnées dans le sens où le QGraphicsScene peut partir du principe que la souris n'est pas dans l'item. À voir.

    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  3. #3
    Candidat au Club
    Inscrit en
    Avril 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Merci pour avoir répondu et de me donner des pistes.

    J'aurais tendance à dire qu'il manque un setInteractive(true) sur le QGraphicsView
    Cela ne marche pas. Par défaut on est a true de toute facon, j'ai fais le test.

    Pour le reste je sais pas encore si j'ai bien compris, je vais quand même essayer de faire quelque chose avec la souris mais en utilisant la méthode void setSelected ( bool selected ); de QGraphicsItem, cela ne marche pas mieux

Discussions similaires

  1. Man signal, man scanf => pas de manuel
    Par weed dans le forum Applications et environnements graphiques
    Réponses: 6
    Dernier message: 17/05/2004, 16h31
  2. erreur ora-12801 : error signaled in parallel query server
    Par dngaya dans le forum Administration
    Réponses: 5
    Dernier message: 15/04/2004, 16h25
  3. [VB6] [MDI] Signaler la fermeture d'une fille à la mère
    Par cpri1shoot dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 13/04/2004, 08h57
  4. Dxdiag me signale que j'ai 510M de ram
    Par Goetz dans le forum DirectX
    Réponses: 1
    Dernier message: 29/09/2003, 14h33
  5. Interception du signal SIGINT
    Par macleod dans le forum MFC
    Réponses: 2
    Dernier message: 01/07/2003, 18h39

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