Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt signals (QueuedConnection and DirectConnection)

I'm having trouble with Qt signals.

I don't understand how DirectConnection and QueuedConnection works?

I'd be thankful if someone will explain when to use which of these (sample code would be appreciated).

like image 266
Nika Avatar asked Feb 24 '13 12:02

Nika


People also ask

What is Qt Queuedconnection?

Queued Connection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. Blocking Queued Connection The slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns.

How do signals work in Qt?

In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal.

Are Qt signals synchronous?

So in normal cases, it will be synchronous and blocking, and with queued connections it will be asynchronous and non-blocking.

Can a Qt signal return a value?

The common wisdom (expressed in the Qt documentation [EDIT: as well as some answers to this question ]) is that no such thing is possible with Qt signals. So: according to the docs, this thing isn't possible.


1 Answers

You won't see much of a difference unless you're working with objects having different thread affinities. Let's say you have QObjects A and B and they're both attached to different threads. A has a signal called somethingChanged() and B has a slot called handleChange().

If you use a direct connection

connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection ); 

the method handleChange() will actually run in the A's thread. Basically, it's as if emitting the signal calls the slot method "directly". If B::handleChange() isn't thread-safe, this can cause some (difficult to locate) bugs. At the very least, you're missing out on the benefits of the extra thread.

If you change the connection method to Qt::QueuedConnection (or, in this case, let Qt decide which method to use), things get more interesting. Assuming B's thread is running an event loop, emitting the signal will post an event to B's event loop. The event loop queues the event, and eventually invokes the slot method whenever control returns to it (it being the event loop). This makes it pretty easy to deal with communication between/among threads in Qt (again, assuming your threads are running their own local event loops). You don't have to worry about locks, etc. because the event loop serializes the slot invocations.

Note: If you don't know how to change a QObject's thread affinity, look into QObject::moveToThread. That should get you started.

Edit

I should clarify my opening sentence. It does make a difference if you specify a queued connection - even for two objects on the same thread. The event is still posted to the thread's event loop. So, the method call is still asynchronous, meaning it can be delayed in unpredictable ways (depending on any other events the loop may need to process). However, if you don't specify a connection method, the direct method is automatically used for connections between objects on the same thread (at least it is in Qt 4.8).

like image 173
Jacob Robbins Avatar answered Sep 29 '22 21:09

Jacob Robbins