Unsolved QTimer destructors
-
Hi all, I sometimes receive this warning during termination of my application:
QObject::killTimer: Timers cannot be stopped from another thread QObject::~QObject: Timers cannot be stopped from another thread
I'm not explicitly calling the destructors in a different thread. Any guesses on how I'm accidentally causing this?
-
@John-Howe
You may not be calling destructors explicitly, but do you parent theQTimer
s to (aQObject
in) another thread? -
@John-Howe said in QTimer destructors:
I'm not explicitly calling the destructors in a different thread. Any guesses on how I'm accidentally causing this?
I'm going to respond to this the same way I had done in the past, here.
Qt is going to free child
QObject
s when the parent is destroyed, so that's how you get to this. Why you get the warning exactly is anyone's guess without more information. -
You simply need to defer starting the timer until after the thread is started because the thread has a different event loop and you want the timer running that event loop not the main thread's. Assume you have two objects, a
QThread
and a QObject-derived object you want to run in that thread, e.g.class MyWorker : public QObject
. Create a slotMyWorker::OnThreadStarted
and there is where you wire up the timeout and start the timer. The essential code to start the thread is below.// main thread application code MyWorker *worker_ = new MyWorker; // do not parent the QObject QThread worker_thread_; worker_->moveToThread(&worker_thread_); connect(&worker_thread_, &QThread::started, worker_ , &MyWorker::OnThreadStarted); connect(&worker_thread_, &QThread::finished, worker_, &QObject::deleteLater); worker_thread_.start();
N.B. The timer should be a member of MyWorker and parented to MyWorker. It's ok to create the timer in the main thread, e.g. in the constructor of MyWorker, but you must defer starting it until the thread is running. Somewhere else in your main application, perhaps a close event, you would typically stop and wait for (join) the worker thread:
worker_thread_.stop(); worker_thread_.quit()