Solved To start the QBasicTimer and execute the timerEvent() within a thread.
-
Hi everyone,
I am working on a multi-threaded GUI application, where I create three threads. These three threads will run continuously and update main thread (GUI thread). One of the thread will start the timer with 10msec as time interval. timerEvent() method will extract the image from camera (every 10ms) and send QImage to GUI thread for updating video widget (using signal and slot mechanism).
Whenever the timer is timed out, main thread is executing timerEvent() method instead of other thread which started the timer. Because of this GUI is becoming less interactive and slow.
Is it possible to make the thread (other than main thread) which starts timer to execute the timerEvent() method?
Thank you in advance.
-
Hi,
You share the code of your thread, it will allow to understand how it is currently working.
-
main.cpp
int main (int argc, char *argv[]) { QApplication a (argc, argv); Viewer *w = new Viewer(); w->show(); a.exec (); return 0; }
viewer.cpp
Viewer::Viewer (QWidget *parent) : QMainWindow (parent), ui (new Ui::Viewer) { .... Thread1 = new work1(this) Thread2 = new work2(this) Thread3 = new video(this) connect(Thread3, SIGNAL(imageReady(QImage ), this, SLOT(setImage(QImage )); Thread3 -> start(); } void setImage(QImage image) { //updates the image in Qlabel widget }
video.cpp
void video::run() { timer.start(10,this); //timer is of QBasicTimer type } void video::timerEvent(QTimerEvent *) { //code for extarcting the image from camera .... emit imageReady(image); }
-
@kole said in To start the QBasicTimer and execute the timerEvent() within a thread.:
void video::run() { timer.start(10,this); //timer is of QBasicTimer type }
The thread object (
Thread3
) is living in the main thread and you pass it as receiver of the timer events. The main thread receiving the timer events is for all intents and purposes correct and expected behavior. -
Hi,
To add to @kshegunov, you thread doesn't run its own event loop since you didn't started it.
-
@kshegunov , @SGaist Thank you for replying. I found this material helpful for understanding the event loop.
But is it possible to make Thread3 process the timerEvent() method? I am thinking to start the thread without parent (in main.cpp along with viewer object) and then process its own events by calling exec() in run() method. Is it right way to do?
main.cpp
int main (int argc, char *argv[]) { QApplication a (argc, argv); Viewer *w = new Viewer(); video *Thread3 = new video(); connect(Thread3, SIGNAL(imageReady(QImage ), w, SLOT(setImage(QImage )); Thread3 -> start(); w->show(); a.exec (); Thread3->quit(); Thread3->wait(); return 0; }
video.cpp
void video::run() { timer.start(10,this); //timer is of QBasicTimer type exec(); } void video::timerEvent(QTimerEvent *) { //code for extarcting the image from camera .... emit imageReady(image); }
-
My advice is to not derive from
QThread
in this case, but use the worker object approach. See here.