handle
handle

Reputation: 6299

Qt emit signal to object moved to thread

In order to initiate stopping a thread by setting a flag (and then returning from within the thread), I need to communicate with it.

The threading is implemented like this

MyClass* obj = new MyClass(0);
connect( this,SIGNAL( stop() ),obj, SLOT(stop()));
emit stop();    // slot is called (qDebug output)

MyThread = new QThread;
obj->moveToThread(MyThread);
connect( ... started() ... quit() ... finished() ... deleteLater() ...
....

emit stop();    // slot isn't called (qDebug output)

The slot does not have any logic yet, it just uses a qDebug() output. The object creation and connections take place in a main window method.

Unfortunately, I can't figure out what I am doing wrong: once the object is moved to the thread, the slot is not run anymore.

Upvotes: 0

Views: 1262

Answers (2)

Jacob Robbins
Jacob Robbins

Reputation: 1920

Maybe you just forgot to copy/paste it in, but you're missing a MyThread->start() call. Also, the line declaring the thread should be QThread * MyThread = new QThread();, but that was probably just a typo.

Now, in your answer, you say that using a Qt::DirectConnection seems to have fixed your problem. However, a slot invoked using a direct connection just calls the slot method directly. The slot method is running, but it's running from the calling thread (where your stop() signal is emitted). This will work even if your thread isn't started. What you really want is for the slot to be invoked over a Qt::QueuedConnection. This will place an event in the worker thread's event loop, which will then invoke the slot. Note that Qt will handle the connection type if you don't specify.

If the queued connection doesn't work, then you're probably blocking the thread's event loop with your work. In your work method, do you ever pass control back to the event loop to allow it to process events? Or does it just run in a while loop waiting for a flag to change state?

Also, your code doesn't compile/run as-is. I assume you're handling the QApplication stuff already - namely, calling QApplication::exec() after everything is set up in you main function. If you don't call exec(), the main event loop is never started.

Upvotes: 2

handle
handle

Reputation: 6299

The debug output actually took place, only after the thread finished its work. Using

connect( this, SIGNAL(stop()), obj, SLOT(stop()), Qt::DirectConnection);

resolved the problem.

Upvotes: -1

Related Questions