I'm writing an application with a button to start/stop a worker thread (which implements QThread
).
The worker thread keeps scheduling a job every few milliseconds.
To terminate the worker thread, I'm calling worker.quit()
(worker.exit(0)
doesn't work either) method from the GUI thread and waiting the finished
signal to be fired.
The problem is that even though the finished
signal is fired, the thread isn't terminated.
Here is a minimal example: https://gist.github.com/NawfelBgh/941babdc011f07aa4ab61570d7b88f08
My interpretation of what happened was wrong: The worker thread was being terminated but the method iter
was getting executed in the main thread as said by @sergey-tachenov and as confirmed from the logging generated with the code:
void run() {
std::cout <<"From worker thread: "<<QThread::currentThreadId() << std::endl;
...
void iter() {
std::cout <<"From thread: "<<QThread::currentThreadId() << std::endl;
...
void MainWindow::on_pushButton_clicked()
{
std::cout <<"From main thread: "<<QThread::currentThreadId() << std::endl;
I switched to a different design which doesn't rely on QTimer
s. But I didn't submit it as an answer since the title of this question is "How to quit the event loop of a worker QThread".
The thread is terminated. Only your timer runs not in the thread you've started but in the main thread, that's why it isn't stopped. This is because it uses queued connections by default and the thread object lives in the thread in which it was created which is the main thread. To fix it:
QThread
. It's usually a bad idea unless you want to actually extend QThread
's functionality.QObject
.moveToThread
to move the worker object to the created thread. It will cause all its slots to fire actually in the thread. If you use default or queued connections, that is.The QThread
docs provide an excellent example on that (the first one).
Note that if you actually want to use data provided by the thread to update GUI, you'll have to somehow correctly publish that data to the GUI thread (possibly using emit
and queued connections) instead of trying to update GUI directly from the thread. And if you want to access shared data, you probably need to guard it with a QMutex
, not like you do with your shared counter.