4
votes

I have a subclass of QObject referred to as myObject, which has a QTimer data member allocated on the heap in the constructor. myObject also has a slot which is connected to the QTimer timeout() signal in the constructor. I refer to the pointer of myObject as myObject_ptr.

I want to run myObject on a different thread from the main thread. Following the relatively new recommendations, I DO NOT subclass QThread. In the main thread, I use myObject as follows:

QThread *thread = new QThread(this);
myObject_ptr->moveToThread(thread);
connect(myObject_ptr, SIGNAL(destroyed(), thread, SLOT(quit())); //thread not needed if no object
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); //to avoid memory leak
connect(thread, SIGNAL(terminated()), thread, SLOT(deleteLater())); //to avoid memory leak
thread->start();

The main thread invokes a function of myObject_ptr which in turn starts the QTimer data member. When it times out, nothing happens, but I expect the slot of myObject to which the timer's timeout() signal is connected to be invoked. What is the problem? How do you make this work. It works flawlessly if myObject is run on the same thread where it was created i.e. main thread.

From all the readings I've done, I think the new thread I am creating might not be processing events because it doesn't have it's own event loop. I also read documentation/articles contrary to that, saying that when the thread starts, the run() function calls exec() and you have an event loop.

Could someone help me please?

I could probably get it to work correctly if I subclass QThread, but based on current recommendations, I would prefer to avoid doing that.

Thank you in advance.

1

1 Answers

3
votes

I solved my problem!! In the constructor of MyObject, the timer is allocated on the heap as follows:

timer_ptr = new QTimer(this);

but to work correctly, it should be:

timer_ptr = new QTimer(0);

and in the destructor, delete the object manually:

timer_ptr->deleteLater();

I guess when they say can't move an object with a parent to a thread, they really do mean ALL objects, including data members of the object actually being moved to the new thread.

Happy coding.