web-dev-qa-db-fra.com

Comment puis-je émettre un signal d'une autre classe?

J'ai un problème avec mon application Qt. J'essaie d'émettre un signal depuis une autre classe (c'est une classe imbriquée de celle dans laquelle le signal est placé).

J'ai déjà connecté le signal avec une fente, ce qui devrait être bien. Mais lorsque j'essaie d'émettre ce signal depuis cette classe imbriquée, j'obtiens l'erreur du compilateur:

ne peut pas appeler la fonction membre sans objet

Qu'est-ce qui ne va pas? J'ai cherché cela dans la documentation de Qt mais je n'ai pas trouvé de solution raisonnable ni même d'explication.

La définition de classe simplifiée se présente comme suit.

class LogWriter : public QDialog
{   
   Q_OBJECT

public:
   class Log : public QObject
   {
      Q_OBJECT

   public:
      bool print;

      Log(bool _print, QString _color, QObject *obj = NULL)
         : QObject(obj)
      {
         print = _print;
         color = _color;
      }
   };

   LogWriter(QWidget * parent = 0);
   ~LogWriter();

public slots:
   void setMinVal();
   void setMediumVal();
   void setHighVal();
   void cleanWindow();
   void appendText(QString &text);

signals:
   void signalLogAppend(QString);
};

Je connecte le signal d'une instance LOW du LogWriter dans le code client à un emplacement en utilisant l'appel de fonction suivant:

connect(&LOW, SIGNAL(signalLogAppend(QString)),
        this, SLOT(appendText(QString&)),
        Qt::DirectConnection);
28
lagoru

Pour comprendre le problème, vous devez comprendre comment les signaux sont émis:

Il s'agit simplement d'un appel de fonction membre non statique et nécessitent donc l'appel d'une instance ("l'expéditeur"). En général, cette instance est this (si vous émettez le signal à partir d'une autre fonction membre non statique de la même classe), la syntaxe d'appel devient donc un appel de fonction normal sans aucun ( littéral). Le mot clé emit est facultatif et est simplement une macro qui ne se développe pas. Les quatre versions suivantes sont toutes identiques lorsqu'elles sont écrites dans une fonction membre de la même classe qui contient le signal:

emit this->signalLogAppend("foo");
emit signalLogAppend("foo");
this->signalLogAppend("foo");
signalLogAppend("foo");

Si vous émettez le signal de la classe externe à partir de la classe interne, le pointeur this fait référence à une instance de la classe interne et il manque donc une instance pour la classe externe. C'est la même chose que si vous appelez une autre fonction de la classe externe depuis la classe interne: le compilateur ne sait pas sur quelle instance d'objet (de la classe externe) l'appeler. Vous devez donc écrire quelque chose comme:

emit someLogWriter->signalLogAppend("foo");

Ici, someLogWriter est l'instance de LogWriter pour laquelle vous souhaitez émettre le signal.

44
leemes