Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Qt] SIGNAL et SLOTS

    2 juillet 2007 à 15:16:59

    Salut, je débute dans Qt et se voulais vous demander si ce code est bon par rapport au signals et slots

    #include <QApplication>
     #include <QFont>
     #include <QPushButton>
     #include <QWidget>
     
     void createWindow(QWidget);

     int main(int argc, char *argv[])
     {
         QApplication app(argc, argv);

         QWidget window;
         window.resize(800, 600);

         QPushButton quit("Quit", &window);
         QPushButton hello("Hello", &window);
         quit.setFont(QFont("arial", 18, QFont::Bold));
         quit.setGeometry(120, 120, 180, 40);
         hello.setGeometry(398, 52, 180, 40);
         QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit()));
         QObject::connect(&hello, SIGNAL(clicked()), &app, SLOT(createWindow()));
         
         
         
         window.show();
         return app.exec();
     }
     
     void createWindow(QWidget windows)
     {
          QPushButton help("Help !", &windows);
          help.setGeometry(400, 400, 50, 100);
          help.show;
          windows.show;
     }


    @+ et merci de vos réponses
    • Partager sur Facebook
    • Partager sur Twitter
      2 juillet 2007 à 17:07:49

      "savoir si mon code est bon".

      Réponse un peu brutale peut-être, mais y a qu'à tester pour le savoir....

      • Partager sur Facebook
      • Partager sur Twitter
      Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
        2 juillet 2007 à 17:58:28

        Tout d'abord, la réponse à ta question se trouve là: Surprise!

        Ensuite, d'un point de vue purement logique: depuis quand "createWindow" est-il un membre de l'objet "app"? et qui plus est, QObject::connect est prévu pour connecter les signaux et des slots; jusqu'a preuve du contraire "createWindow" n'est ni l'un, ni l'autre.
        Conclusion: ton code est tout-à-fait faux et même non-compilable (ou même pré-compilable). Ta façon de faire n'est pas compatible avec la "programmation Qt": il y a une notion d'orienté-objet extrêmement forte avec Qt, or ce que tu fais là, c'est du procédural pur et dur.
        • Partager sur Facebook
        • Partager sur Twitter
          3 juillet 2007 à 0:41:44

          Salut à toi gogeta1 ;) !!

          Je dis comme les autres, à savoir si ton code fonctionne, c'est à toi de le tester ;) !!

          Pour les signals et slots, je comprends ce que tu as voulu faire (j'ai fais la même "erreur"), mais ce n'est pas valide comme méthode(je ne sais pas si ça compile ou pas?).

          Il y, d'après moi, deux souçis:

          Premier souçi: comme tu le dis toi même, Qt fonctionne avec des signals et des slots, or ce ne sont pas de simples fonctions. Je ne suis pas encore assez calé pour t'expliquer correctement, mais les signals et slots, sont en quelques sorte des "fonctions" (vais me faire taper par les vétérans ^^ ...) à l'intérieur de la classe (tu as du remarquer qu'il y a des slots spécifique en fonction du bouton, slider, employé.

          En gros, il faudra d'abord dériver la classe du widget que tu emploie (tu créé une nouvelle classe qui hérite de celle-ci), et lui créer un nouveau signal, ou slot.

          Deuxième souçi: il se rapporte à la "synchronisation" signals/slots au niveau des paramètres. Mon explication n'est pas très claire... Si tu préfères, tu ne peux pas avoir un signal avec paramètre et un slot sans.
          Il faut aussi que ces paramètres soient identiques (du genre un int). C'est un peu bizarre, mais ça veux dire que ta fonction "createWindow(QWidget windows)", qui admet un paramètre, ne peux pas aller avec le signal "clicked()" qui n'en comporte aucun.

          Je laisse la main, à quelqu'un de plus expérimenté que moi en la matière, car c'est tout frai pour moi aussi, et j'ai peur de t'embrouiller plus qu'autre chose :p ...

          Pour revenir à ce que Gravstein a dit à propos de ta façon de programmer avec Qt :) :

          J'ai beau être d'accord avec lui, je fais exactement pareil que toi :-° , c'est à dire que je suis encore débutant en POO, et bien que j'ai compris tout le concept, et que je commence à avoir le reflexe "objet" (savoir remettre en question l'organisation du programme, toujours se poser la question "Et si?" de façon à obtenir quelque chose d'êtremement maléable à la fin), je programme encore comme toi: c'est à dire en procédural (coller tout son code à la suite, sans vrai dynamisme, ou sans vraiment réfléchir au fonctionnement).

          Mon conseil (c'est ce que je fais actuellement) serais de garder le procédural si c'est juste pour tester des fonctionnalités (tester des nouvelles classes que tu découvres dans la doc, tester des fonctions au pif pour voir leur effet, etc), mais c'est tout.

          En parallèle, moi je lis (et t'invite à lire aussi) les tutos de Trolltech, et surtout examiner (pas simplement survoler, mais bien comprendre l'utilité de chaque ligne de code) les exemples fournis dans la doc afin d'en extraire tout les fondements quant au fonctionnement Qt (j'ai en effet l'impression que les 3/4, voire les 9/10 de la prog Qt passe par des classes).
          En soit, si tu as, acquis les bases du C++, et/ou commencé à te servir d'une autre librairie, tu devrais arriver à t'en sortir ne serait-ce qu'avec la doc fournie ;) .

          Je sais que ça peut paraître un peu barbare et perturbant de fouiller "aveuglement" dans la doc, et qu'un tuto de M@teo serait plus que bienvenu, mais chez moi ça a marché jusqu'à présent :p ; et même si ce n'est pas la méthode la plus rapide et la meilleure, c'est certainement la plus glorifiante!

          J'ai seulement lu ses tutos C (c'était avant que les tutos C++ soit publiés) en m'accompagnant de deux bouquins sur le C++ que j'ai chez moi (les livres servent à approfondir dans le plus technique, mais le concept, seul M@teo m'a permis de bien l'assimiler et le comprendre ;) ), j'ai par la suite feuilleté les deux premièrs tutos sur la SDL, et après un "test-run", j'étais parti pour me "démerder" tout seul ^^ avec la doc de la SDL, et maintenant Qt.

          Bonne chance en tout cas ;)
          • Partager sur Facebook
          • Partager sur Twitter
            3 juillet 2007 à 10:02:46

            Merci beaucoup pour tes conseils et ça me fait plaisir de voir que je ne suis pas le "seul" dans "cette situation". Tout le monde y est passé, ça me rassure.

            Sinon, j'ai essayé de commencé à lire les tutos qu'il y a sur la doc de QT mais je n'ai que les bases en anglais, c'est un peu difficile. Mais bon ...

            "QObject::connect() is perhaps the most central feature of Qt." (tirée de la doc de QT)
            Si j'ai bien compris, cette fontion est la chose la plus importante dans QT. J'ai compris comment ça marche mais... Je n'arrive pas à écrire les méthodes.

            C'est vrai que je ne voudrais pas trop en demander, mais pouvez-vous m'expliquer ce code? :
            #include <QObject>

             class Counter : public QObject
             {
                 Q_OBJECT

             public:
                 Counter() { m_value = 0; }

                 int value() const { return m_value; }

             public slots:
                 void setValue(int value);

             signals:
                 void valueChanged(int newValue);

             private:
                 int m_value;
             };

            void Counter::setValue(int value)
             {
                 if (value != m_value) {
                     m_value = value;
                     emit valueChanged(value);
                 }
             }


            Merci de votre aide et de votre soutien aussi ;)
            • Partager sur Facebook
            • Partager sur Twitter
              3 juillet 2007 à 10:27:12

              #include <QObject>

               class Counter : public QObject // une classe simple héritant de QObject (indispensable pour pouvoir utiliser slots et signals)
               {
                   Q_OBJECT // obligatoire si on crée des slots ou signals dans cette classe

               public:
                   Counter() { m_value = 0; }

                   int value() const { return m_value; }

               public slots: // cette fonction est un slots
                   void setValue(int value);

               signals: // cette entête est un signal (pas de définition car automatiquement fait pas moc)
                   void valueChanged(int newValue);

               private:
                   int m_value;
               };

              void Counter::setValue(int value)
               {
                   if (value != m_value) { // si la valeur est différente de l'ancienne pour éviter les boucles infinies.
                       m_value = value; // on la change
                       emit valueChanged(value); // on lance le signal comme quoi la valeur à changée, les slots connectés à ce signal en seront avertis.
                   }
               }
              • Partager sur Facebook
              • Partager sur Twitter
                3 juillet 2007 à 10:43:07

                Si on a
                Counter a, b;

                que ce passe-t-il lorsqu'on fait ceci :
                QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));
                a.setValue(12);   
                b.setValue(48);
                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  3 juillet 2007 à 11:29:31

                  Tu appelles la méthode setValue de a. Sa valeur passe à 12, puis a émet le signal valueChanged(int). Ce signal est connecté au slot setValue(int) de b, donc la valeur de b passe également à 12. Puis b émet aussi le signal valueChanged(int), mais qui n'est connecté à aucun slot, donc rien ne se passe.

                  Puis tu appelles la méthode setValue de b. Sa valeur passe à 48, puis b émet le signal valueChanged(int), qui n'est connecté à aucun slot : rien de plus ne se passe.

                  Au final :
                  a.value() == 12;
                  b.value() == 48;
                  • Partager sur Facebook
                  • Partager sur Twitter
                    3 juillet 2007 à 11:30:24

                    Une boucle infinie, à prioris.. Maintenant, il y a peut-être une protection... A vérifier.

                    Edit: Mal lu le code...
                    • Partager sur Facebook
                    • Partager sur Twitter

                    [Qt] SIGNAL et SLOTS

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown