Partage
  • Partager sur Facebook
  • Partager sur Twitter

QT signal dans classe dérivée

Classe abstraite

Sujet résolu
    8 octobre 2018 à 16:19:48

    Salut, 

    J'ai un souci avec une classe abstraite et surtout un signal dans la classe dérivée.

    Class Base, avec des signaux.

    Classe Dérivée, avec son propre signal. Lorsque je fait un emit monSignal(); ça passe à la complétion, mais pas à la compilation. Pour que mon signal passe à la compil, il faut que je le déplace dans les signaux de Base....

    Est-ce normal??

    Ensuite, dans une classe qui utilise ma dérivée, je fais Base *MonObj, puis monObj = new base(), ça compil et tout, mais impossible de voir les méthodes de ma dérivée, je suis obligé de faire un static_cast<Dérivée *>(monObj)->maMéthode();

    Encore une fois, est-ce normal??

    Merci pour tout.

    • Partager sur Facebook
    • Partager sur Twitter
      8 octobre 2018 à 16:42:58

      Il faut donner ton code quand tu as un problème, c'est plus simple pour comprendre.

      pilou007 a écrit:

      Ensuite, dans une classe qui utilise ma dérivée, je fais Base *MonObj, puis monObj = new base(), ça compil et tout, mais impossible de voir les méthodes de ma dérivée, je suis obligé de faire un static_cast<Dérivée *>(monObj)->maMéthode();

      Encore une fois, est-ce normal??

      Oui, c'est normal. Si tu ne comprends pas pourquoi, ca devrait etre expliqué dans ton cours.

      Et je suppose que ton premier problème avec emit vient de la meme erreur.

      Hors sujet : ne separes pas declaration et initiatialisation de tes variables.

      • Partager sur Facebook
      • Partager sur Twitter
        8 octobre 2018 à 17:12:24

        Salut,

        pilou007 a écrit:

        je fais Base *MonObj, puis monObj = new base(), ça compil et tout, mais impossible de voir les méthodes de ma dérivée, je suis obligé de faire un static_cast<Dérivée *>(monObj)->maMéthode();


        Si tu fais ça, c'est que tu n'as pas compris le polymorphisme, ce n'est pas un problème de Qt ou de signal, relis ton cours attentivement
        • Partager sur Facebook
        • Partager sur Twitter
        Dream on, Dream on, Dream until your dream comes true
          9 octobre 2018 à 14:19:35

          Salut, 

          Ce serait gentil de mettre une réponse plutôt que de renvoyer vers mon cours, lorsqu'on fait des recherches sur internet, on aimerait et vous les premier je suppose avoir une réponse plutôt qu'une réponse qui te dit "revoie ton cours", non??

          Bref, quelque soit le cours que j'ai trouvé , je n'ai pas de réponse et encore moins concernant les signaux....

          Je ne vous mets pas mon code car très long... Mais s'il le faut je ferai un code raccourci...

          Merci

          ERRATUM!!

          Lorsque j'ai écrit 

          Ensuite, dans une classe qui utilise ma dérivée, je fais Base *MonObj, puis monObj = new base(), ça compil et tout, mais impossible de voir les méthodes de ma dérivée, je suis obligé de faire un static_cast<Dérivée *>(monObj)->maMéthode();
          
          Encore une fois, est-ce normal??

          J'ai fais une erreur, en réalité, ce que je fais, c'est bien:

          Ensuite, dans une classe qui utilise ma dérivée, je fais Base *MonObj, puis monObj = new Dérivée(), ça compil et tout, mais impossible de voir les méthodes de ma dérivée, je suis obligé de faire un static_cast<Dérivée *>(monObj)->maMéthode();
          
          Encore une fois, est-ce normal??

          -
          Edité par pilou007 9 octobre 2018 à 14:27:17

          • Partager sur Facebook
          • Partager sur Twitter
            9 octobre 2018 à 14:36:18

            pilou007 a écrit:

            Ce serait gentil de mettre une réponse plutôt que de renvoyer vers mon cours, lorsqu'on fait des recherches sur internet, on aimerait et vous les premier je suppose avoir une réponse plutôt qu'une réponse qui te dit "revoie ton cours", non??

            Si le probleme est que tu n'as pas assimilé le debut du cours, cela ne sert a rien de te donner d'autres reponses que "relire ton cours".

            On t'a deja repondu : oui, c'est normal. 

            • Partager sur Facebook
            • Partager sur Twitter
              9 octobre 2018 à 14:52:15

              pilou007 a écrit:

              Ce serait gentil de mettre une réponse plutôt que de renvoyer vers mon cours


              Pour avoir des réponses, il faut poser des questions. Là ta question est "est-ce normal ?", on t'a répondu que oui.

              Et ensuite on essaie de t'aider à résoudre le fond de ton problème en t'aiguillant, et avec ce que tu avais écrit on aurait dit qu'il s'agissait d'une non assimilation du principe de polymorphisme qui représente un bon chapitre de cours, donc évidemment qu'on te redirige vers un cours qui aura été travaillé et affiné plutôt que de tout réécrire sur le forum, avec une mise en forme moins adapté et des risques que ce soit incomplet ou erroné

              pilou007 a écrit:

              Je ne vous mets pas mon code car très long... Mais s'il le faut je ferai un code raccourci...

              Oui, il le faut

              EDIT :

              as-tu pensé à réécrire la macro Q_OBJECT dans ta classe dérivée ?

              -
              Edité par romantik 9 octobre 2018 à 15:01:02

              • Partager sur Facebook
              • Partager sur Twitter
              Dream on, Dream on, Dream until your dream comes true
                9 octobre 2018 à 16:16:13

                Bon, pour le problème du signal, j'ai ajouté Q_OBJECT et il faut éffacé tous le répertoire du debug, et là ça marche...

                Pour le cast, j'ai bien compris, c'est juste que j'vais cru voir un exemple sans cast.

                Merci, bye

                Bon c'est vrai que vous répondez à la question, "est-ce normal?" Maintenant, je ne sais pas si ça aide....

                Bref.

                Voici mon code raccourci:

                Classe de base.h

                #ifndef MAINWINDOWCONTROLER_H
                #define MAINWINDOWCONTROLER_H
                
                #include <QObject>
                #include <QTimer>
                #include <QString>
                
                class MainWindowControler : public QObject
                {
                    Q_OBJECT
                
                public:
                    MainWindowControler();
                    ~MainWindowControler();
                    bool startRecord();
                    void stopRecord();
                
                private:
                    virtual void recordDataInFile() = 0;
                    virtual void handleDataReceived(const TPCANMsg pTpcanMsg, const TPCANTimestamp pFrameTimeStamp) = 0;
                
                signals:
                    void emitDataToView();
                
                public slots:
                    void displayStatus();
                    virtual void updateIhm() = 0;
                
                private:
                    // des variables
                };
                
                #endif // MAINWINDOWCONTROLER_H
                

                Son implémentation

                #include "mainwindowcontroler.h"
                
                MainWindowControler::MainWindowControler() : QObject ()
                {
                   
                }
                
                MainWindowControler::~MainWindowControler()
                {
                    
                }
                
                bool MainWindowControler::startRecord()
                {    
                    return true;
                }
                
                void MainWindowControler::stopRecord()
                {
                   
                }
                
                // D'autres méthodes
                

                La classe dérivée.h

                #ifndef MABCONTROLMAINWINDOWCONTROLER_H
                #define MABCONTROLMAINWINDOWCONTROLER_H
                
                #include "Generic/mainwindowcontroler.h"
                
                class MabControlMainWindowControler : public MainWindowControler
                {
                    Q_OBJECT
                
                public:
                    MabControlMainWindowControler();
                    ~MabControlMainWindowControler();
                    
                private:
                    void recordDataInFile();
                    void handleDataReceived(const TPCANMsg pTpcanMsg, const TPCANTimestamp pFrameTimeStamp);
                    bool statusCom() const;
                
                private slots:
                    void updateIhm();
                
                signals:
                    void test();
                
                private:
                    // Des variables
                };
                
                #endif // MABCONTROLMAINWINDOWCONTROLER_H

                Son implémentation:

                #include "mabcontrolmainwindowcontroler.h"
                
                MabControlMainWindowControler::MabControlMainWindowControler()
                {
                    // du code
                }
                
                MabControlMainWindowControler::~MabControlMainWindowControler()
                {
                
                }
                
                void MabControlMainWindowControler::recordDataInFile()
                {
                    // du code
                }
                
                void MabControlMainWindowControler::handleDataReceived(const TPCANMsg pTpcanMsg, const TPCANTimestamp pFrameTimeStamp)
                {    
                    // Du code
                }
                
                void MabControlMainWindowControler::updateIhm()
                {
                    emit emitDataToView(); // ça ça compile
                    //emit test(); // ça ça ne compile pas
                }
                
                bool MabControlMainWindowControler::statusCom() const
                {
                    return m_statusCom;
                }

                et l'utilisation.h:

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <QMainWindow>
                #include <QCloseEvent>
                #include <QMessageBox>
                
                #include "mabcontrolmainwindowcontroler.h"
                #include "constantesmabcontrol.h"
                
                namespace Ui {
                class MainWindow;
                }
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    explicit MainWindow(QWidget *parent = nullptr);
                    ~MainWindow();
                
                private:
                    void initCanDeviceComboBox();
                
                private slots:
                    void updateView();
                    void updateStatusBar(const QString pStatus);
                    void msgToDisplay(const QString pMsgToDisplay);
                    void on_cbSelectPeakCan_currentIndexChanged(int pIndex);
                    void on_pbRecord_toggled(bool pChecked);
                
                private:
                    Ui::MainWindow *ui;
                
                    MainWindowControler *m_mainControler;
                };
                
                #endif // MAINWINDOW_H

                Et l'utilisation.cpp

                #include "mainwindow.h"
                #include "ui_mainwindow.h"
                
                MainWindow::MainWindow(QWidget *parent) :
                    QMainWindow(parent),
                    ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    m_mainControler = new MabControlMainWindowControler();
                    
                    if(m_mainControler != nullptr)
                    {
                        //m_mainControler->getCanC..... // ne voit pas la complétion....
                    }
                    else
                    {
                        QMessageBox::critical(this, tr("Application"), tr("Impossible de démarrer l'application correctement"), QMessageBox::Ok);
                
                        this->~MainWindow();
                    }
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                }

                Merci pour votre aide






                -
                Edité par pilou007 9 octobre 2018 à 17:00:43

                • Partager sur Facebook
                • Partager sur Twitter
                  9 octobre 2018 à 17:41:04

                  pilou007 a écrit:

                  Bon c'est vrai que vous répondez à la question, "est-ce normal?" Maintenant, je ne sais pas si ça aide....

                  Exactement, c'est ce que j'essaie de te dire, sans les bonnes questions on n'obtient pas les bonnes réponses

                  Quand on parle du code raccourci, on parle normalement du code minimal pour reproduire l'erreur, pas du code total en virant ce qui prend trop de place (c'est un moyen d'arriver au code minimal, mais alors il faut le faire jusqu'au bout tout en vérifiant que ça compile et que ça soit cohérent)

                  Pour ton second soucis, je pense toujours que tu n'as pas saisi le polymorphisme, lorsque ton pointeur est de type Base alors tu manipules une instance qui a la forme d'une Base, c'est normal que tu ne puisses pas accéder aux spécificités de Dérivé sans caster, mais le cast reste une opération à utiliser avec parcimonie, il faut t'assurer qu'à ce point du programme tu ne peux rien avoir d'autre qu'un Dérivé dans le pointeur.
                  D'ailleurs, si ton objet à la responsabilité de la création et la destruction de celui-ci, et qu'en plus il a besoin des spécificité de Dérivé, pourquoi manipule-t-il un pointeur de Base au lieu d'un pointeur de Dérivé ? ça ne fais pas trop sens

                  Par contre c'est vrai que je ne vois pas pour ton premier soucis, peux-tu faire l'effort de trouver le code minimal dont je parlais ?
                  Malheureusement, dans mon environnement actuel de travail je n'ai pas Qt, je ne peux pas faire le test

                  Aussi, si l'opérateur new échoue il lève une exception, ton test n'a donc pas de sens
                  Tu as deux choix :
                   - Soit tu gère l'erreur par les exceptions avec un bloc try{}catch(){}
                   - Soit tu spécifies que tu ne souhaites pas d'exception `new(std::nothrow) Derive()` et tu gardes ta gestion testant le nullptr

                  Cependant dans cette gestion justement, c'est pas une bonne idée de vouloir s'autodétruire, puisque rien n'aura averti la fonction instanciatrice que quelque chose s'est mal déroulé (c'est justement le rôle des exceptions)

                  -
                  Edité par romantik 9 octobre 2018 à 17:54:16

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Dream on, Dream on, Dream until your dream comes true
                    10 octobre 2018 à 9:16:45

                    Bon, pour le problème du signal, j'ai ajouté Q_OBJECT et il faut éffacé tous le répertoire du debug avant de tout recompiler, et là ça marche... Mais ça c'est pas dans le cours, loool et j'arrive à reproduire le problème quand je veux...

                    Pour le cast, j'ai bien compris, c'est juste que j'avais cru voir un exemple sans cast. Maintenant, c'est vrai que je ne manipule pas très souvent des classe abstraite dans ce que je fais. Et donc j'ai essayé de suivre les tuto, mais pas fait attention au cast.

                    Dans mon cas, c'est vrai que je n'ai pas besoin d'un objet de type Base, et c'est donc comme ça que je m'en suis sorti.

                    Merci pour votre aide. Bye

                    -
                    Edité par pilou007 10 octobre 2018 à 9:22:47

                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 octobre 2018 à 9:42:50

                      pilou007 a écrit:

                      Bon, pour le problème du signal, j'ai ajouté Q_OBJECT et il faut éffacé tous le répertoire du debug avant de tout recompiler, et là ça marche... Mais ça c'est pas dans le cours, loool et j'arrive à reproduire le problème quand je veux...


                      Ah voilà, elle manquait lorsque le problème est apparu

                      Du coup c'est normal, le mecanisme signal/slot ne fait pas partie du standard et Qt a décidé de l'implémenter au travers un système de meta-objet. Or la macro Q_OBJECT permet de génerer les meta-objets, donc pas de macro pas de meta-objet, pas de meta-objet pas de signaux, pas de signaux ... pas de signaux :p

                      Et ces meta-objets sont créés par le système de build, avant la compilation, par qmake si c'est ce que t'utilise, ou plus précisément par le moc (MetaObject Compiler), il génère les fichiers préfixés par "moc_" qui contiennent les classes représentant le meta-objet
                      Donc si tu as une modification de ce type, il faut invoquer qmake avant de faire la compilation

                      Et ensuite le mécanisme devient complexe, très spécifique à Qt, ça ne vaut pas le coup de plonger dedans à moins d'y en avoir une vraie utilité

                      Du coup ça devient très compliqué pour détaillé tout ça un cours, surtout s'il est destiné aux débutant, donc la meilleure chose que peux faire le cours, c'est insister dessus avec un bon warning disant "surtout n'oubliez pas la macro Q_OBJECT lorsque vous déclarez un QObject".
                      Si cet avertissement n'est pas dans ton cours, il manque effectivement car c'est une erreur facile à faire. Quel est ce cours que tu suis ?

                      Ensuite si tu veux en savoir plus sur le système de metaObject, outre la documentation de Qt, tu peux jeter un oeil aux très bon article du blog woboq, détenu par deux anciens core developer Qt expert.

                      EDIT :

                      Et si ton soucis est résolu, tu peux l'indiquer en passant le sujet à "résolu", ça indiquera aux gens qui font des recherches pour un problème similaire qu'il y a des éléments de réponse ici et aussi ça évite que des gens qui regarde les sujets pour voir s'ils peuvent apporté de l'aide s'attarde inutilement sur un sujet qui n'en a plus besoin

                      Parce que lorsqu'on fait des recherches sur internet, on aimerait et toi le premier je suppose savoir quels sujets sont les plus susceptibles de nous donner des réponses, non ?? ;P

                      -
                      Edité par romantik 10 octobre 2018 à 10:14:06

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Dream on, Dream on, Dream until your dream comes true
                        10 octobre 2018 à 15:22:35

                        Bon, pour le problème du signal, j'ai ajouté Q_OBJECT et il faut éffacé tous le répertoire du debug avant de tout recompiler, et là ça marche... Mais ça c'est pas dans le cours, loool et j'arrive à reproduire le problème quand je veux...

                        Pour le cast, j'ai bien compris, c'est juste que j'avais cru voir un exemple sans cast. Maintenant, c'est vrai que je ne manipule pas très souvent des classe abstraite dans ce que je fais. Et donc j'ai essayé de suivre les tuto, mais pas fait attention au cast.

                        Dans mon cas, c'est vrai que je n'ai pas besoin d'un objet de type Base, et c'est donc comme ça que je m'en suis sorti.

                        Merci pour votre aide. Bye

                        • Partager sur Facebook
                        • Partager sur Twitter

                        QT signal dans classe dérivée

                        × 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