Question

La documentation

de Qt indique que les signaux et les emplacements peuvent être direct , en file d'attente et auto .

Il a également indiqué que si l'objet possédant le logement 'vit' dans un thread différent de celui possédant le signal, émettre un tel signal ressemblerait à l'envoi d'un message - le signal émis sera renvoyé instantanément et la méthode slot sera appelée dans la boucle d'événements du thread cible. .

Malheureusement, la documentation ne spécifie pas que "vies" signifie et qu'aucun exemple n'est disponible. J'ai essayé le code suivant:

main.h:

class CThread1 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        msleep( 200 );
        std::cout << "thread 1 started" << std::endl;
        MySignal();
        exec();
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

main.cpp:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & oThread2, SLOT( MySlot() ) );
    oThread1.start();
    oThread2.start();
    oThread1.wait();
    oThread2.wait();
    return a.exec();
}

La sortie est:

thread 2 started
thread 1 started

MySlot () n'est jamais appelé :(. Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Votre code pose quelques problèmes:

  • comme dit par Evan, le mot clé emit est manquant
  • tous vos objets vivent dans le fil principal, seul le code des méthodes d'exécution vivent dans d'autres threads, ce qui signifie que l'emplacement MySlot serait appelé dans le fil principal et je ne suis pas sûr que ce soit ce que vous voulez
  • votre emplacement ne sera jamais appelé car la boucle d'événement principale ne sera jamais lancée: vos deux appels à wait () expireront seulement après un temps très long (et vous tuez probablement votre application avant qu'elle ne survienne) et je Ne pensez pas que ce soit ce que vous voulez non plus, de toute façon ils n’ont vraiment aucune utilité dans votre code.

Ce code fonctionnera probablement (bien que je ne l’aie pas testé) et je pense qu’il fait ce que vous voulez qu'il fasse:

class MyObject : public QObject
{
    Q_OBJECT
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

class CThread1 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 1 started" << std::endl;
        int i = 0;
        while(1)
        {
           msleep( 200 );
           i++;
           if(i==1000)
              emit MySignal();
        }
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    MyObject myObject;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & myObject, SLOT( MySlot() ) );
    oThread2.start();
    myObject.moveToThread(&oThread2)
    oThread1.start();
    return a.exec();
}

Maintenant, MyObject vivra dans thread2 (grâce à moveToThread).

MySignal devrait être envoyé à partir du thread1 (bien que je ne sois pas sûr, il pourrait être envoyé à partir du thread principal, cela n'a pas vraiment d'importance).

Aucune boucle d'événement n'est nécessaire dans thread1, car l'émission d'un signal ne nécessite pas de boucle d'événement. Une boucle d'événement est nécessaire dans thread2 (lanchée par exec ()) pour recevoir le signal.

MySlot sera appelé dans thread2.

Autres conseils

Ne sous-classe pas QThread pour Qt 4.4 +

Bien que la réponse d'Aiua soit bonne, je voudrais signaler quelques problèmes avec QThread et Qt 4.6 ou 4.7.

Cet article le résume: http: / /blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

Manque de documentation de la part de Qt

Malheureusement, le problème provient d'un manque de mises à jour de la documentation. Avant Qt 4.4, QThread n’avait aucune implémentation run () par défaut, ce qui signifiait que vous deviez sous-classer QThread pour pouvoir l’utiliser.

Si vous utilisez Qt 4.6 ou 4.7, alors vous devriez certainement pas la sous-classe QThread.

Utilisez moveToThread

La clé pour obtenir des emplacements à exécuter dans un thread de travail consiste à utiliser la méthode moveToThread comme l'a souligné Aiua.

vous devriez émettre le signal pour démarrer votre fonction de fil comme

emit operateCut(examId,examName_examTemplate[examName].studentIdRec,examName_examTemplate[examName].choiceRecA,examName_examTemplate[examName].choiceRecB,examName_examTemplate[examName].objectRecA,examName_examTemplate[examName].objectRecB);

vous pouvez ajouter plus d'un argument dans ce signal

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top