Bonsoir,
J'ai créé un petit projet avec Qt Creator pour apprendre à manipuler les threads avec QThread. Ce projet qui n'a qu'un but ludique consiste à créer une sorte de métronome dans un thread différent du thread principal. Jusque là, rien d'anormal.
Voici le fichier main.cpp
Comme on peut le voir, le métronome (classe MyClockwork) possède deux slots publics, start() et stop(), ainsi qu'un signal tick(). Par ailleurs, le slot stop() est appelé quand l'application est sur le point de quitter; le problème réside là.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <QApplication> #include "mygui.h" #include "myclockwork.h" int main(int argc, char* argv[]) { QApplication app(argc, argv); MyGui gui; MyClockwork clockwork; app.connect(&clockwork, SIGNAL(tick()), &gui, SLOT(tick())); app.connect(&app, SIGNAL(aboutToQuit()), &clockwork, SLOT(stop())); gui.show(); clockwork.start(); return app.exec(); }
Voici les fichiers liés à la classe du métronome:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifndef MYCLOCKWORK_H #define MYCLOCKWORK_H #include <QObject> #include <QApplication> #include <QThread> #include <QTimer> class MyClockwork : public QObject { Q_OBJECT public: MyClockwork(QObject* parent = 0); ~MyClockwork(); public slots: void start(); void stop(); signals: void tick(); private: QThread* m_thread; QTimer* m_timer; private slots: void timerFired(); }; #endif // MYCLOCKWORK_HLe problème est que, lorsque je renvoie le minuteur m_timer dans le thread principal via la commande m_timer->moveToThread(QApplication::instance()->thread()), je reçois l'erreur suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include "myclockwork.h" MyClockwork::MyClockwork(QObject* parent) : QObject (parent) , m_thread (new QThread) , m_timer (new QTimer) { m_timer->setSingleShot(false); } MyClockwork::~MyClockwork() { delete m_timer; delete m_thread; } void MyClockwork::start() { m_timer->setInterval(1000); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerFired()), Qt::DirectConnection); m_timer->start(); m_timer->moveToThread(m_thread); m_thread->start(); } void MyClockwork::stop() { if(m_thread->isRunning()) { m_timer->moveToThread(QApplication::instance()->thread()); m_thread->quit(); } m_timer->stop(); disconnect(m_timer, SIGNAL(timeout()), this, SLOT(timerFired())); } void MyClockwork::timerFired() { emit tick(); }
En gros, l'application ne parvient pas à mettre l'objet QTimer dans le thread-cible.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 QObject::moveToThread: Current thread (0x3779a8) is not the object's thread (0x7262a0). Cannot move to target thread (0x3779a8)
Pourquoi? Je ne sais pas; c'est pourquoi je sollicite votre aide.
Merci d'avance.
Adishatz!
PS: Quand l'application est terminée, j'obtiens aussi cette erreur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part QObject::killTimer: timers cannot be stopped from another thread
Partager