La documentation de Qt indique que les signaux et les emplacements peuvent être direct
, queued
et auto
.
Il a également déclaré que si l'objet qui possède le slot `` vit '' dans un thread différent de l'objet qui possède le signal, émettre un tel signal sera comme publier un message - le signal émis reviendra instantanément et la méthode du slot sera appelée dans la boucle d'événements du thread cible.
Malheureusement, la documentation ne précise pas que "vies" signifie et 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ée :(. Qu'est-ce que je fais mal?
Il y a pas mal de problèmes avec votre code:
Ce code fonctionnerait très probablement (même si je ne l'ai 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é depuis le thread1 (je ne suis pas sûr de celui-là, il pourrait être envoyé depuis le 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 n'a pas besoin d'une boucle d'événement. Une boucle d'événement est nécessaire dans thread2 (lancé par exec ()) pour recevoir le signal.
MySlot sera appelé dans thread2.
Bien que la réponse d'Aiua soit bonne, je tiens à souligner certains 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/
Malheureusement, le problème provient d'un manque de mises à jour de la documentation. Avant Qt 4.4, QThread n'avait pas d'implémentation run () par défaut, ce qui signifiait que vous deviez sous-classer QThread pour l'utiliser.
Si vous utilisez Qt 4.6 ou 4.7, vous devriez certainement pas sous-classe QThread.
La clé pour obtenir des emplacements à exécuter dans un thread de travail est d'utiliser la méthode moveToThread comme l'a souligné Aiua.
vous devez émettre le signal pour démarrer votre fonction de thread 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 plusieurs arguments dans ce signal