Bonjour à tous.
J'ai un problème avec un programme que je développe sous Qt Creator.
Ce programme est composé de son thread principal, celui de la fenêtre graphique EmulatorWindow héritant de QMainWindow, et d'un second thread héritant de QThread chargé de se connecter à un port pour l'écouter.
La classe du thread "écouteur" dispose d'un pointeur sur la classe de la fenêtre graphique afin de pouvoir appeler la fonction de cette dernière servant à afficher du texte (display()), dans le but de rendre compte en temps réel de l'activité du thread écouteur.
Il y a donc dans la fonction run() du thread écouteur plusieurs instructions du genre window->display("chaine"). Le compilateur ne râle pas, mais à l'exécution, et seulement au lancement du thread écouteur, ces instruction provoquent l'erreur suivante :
" QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x997450), parent's thread is QThread(0x997180), current thread is QThread(0x9985a0)
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().) "
Cette erreur ne fait pas planter le programme ni n'empêche le thread écouteur de tourner, seulement les appels à display ne fonctionnent pas.
Donc, si quelqu'un a une solution pour réparer ça, ou même une autre façon de faire susceptible de répondre à mon besoin, je suis preneur.
EmulatorWindow.hApplicationThread.h (le thread écouteur)
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 #ifndef EMULATORWINDOW_H #define EMULATORWINDOW_H #include <QMainWindow> class ApplicationThreader; namespace Ui { class EmulatorWindow; } class EmulatorWindow : public QMainWindow { Q_OBJECT public: explicit EmulatorWindow(QWidget *parent = 0); ~EmulatorWindow(); void display(std::string s); private: Ui::EmulatorWindow *ui; ApplicationThreader* thread; public slots: void updateDisplaying(); }; #endif // EMULATORWINDOW_HApplicationThreader.cpp
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 #ifndef APPLICATIONTHREADER_H #define APPLICATIONTHREADER_H #include <QTimer> #include <QThread> #include <string> #include <windows.h> class EmulatorWindow; class ApplicationThreader : public QThread { public: ApplicationThreader(EmulatorWindow* wind); QTimer* getTimer(); private: EmulatorWindow* parent; QTimer timer; HANDLE port; void run(); };EmulatorWindow.cpp
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 #include "ApplicationThreader.h" #include "EmulatorWindow.h" #include <iostream> using namespace std; ApplicationThreader::ApplicationThreader(EmulatorWindow* wind): parent(wind), timer(this) { timer.start(50); } QTimer* ApplicationThreader::getTimer() { return &timer; } void ApplicationThreader::run() { parent->display("chaine"); //[...] sleep(3); }
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 #include "EmulatorWindow.h" #include "ApplicationThreader.h" #include "ui_EmulatorWindow.h" EmulatorWindow::EmulatorWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::EmulatorWindow), thread(new ApplicationThreader(this)) { ui->setupUi(this); QObject::connect(ui->pushButton, SIGNAL(clicked()), thread, SLOT(start())); QObject::connect(thread->getTimer(), SIGNAL(timeout()), this, SLOT(updateDisplaying())); } EmulatorWindow::~EmulatorWindow() { delete ui; } void EmulatorWindow::updateDisplaying() { ui->label->setText((thread->isRunning() ? "Running" : "Standby")); } void EmulatorWindow::display(std::string s) { ui->plainTextEdit->appendPlainText(QString::fromStdString(s)); }
Partager