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).
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).
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).
B
into A
- you can let the user of the two classes determine what should happen when somethingChanged
is emitted from A
. Does that make sense? –
Cradle Qt::QueuedConnection
as a param ? The reason I ask this is that in many places specifying Qt::QueuedConnection
or direct is a optional param. Does it mean that Qt takes care of the decision itself whether to "enqueue the signal or call direct" ? –
Judsen Qt::AutoConnection
. If the emitter & receiver are in the same thread, a DirectConnection
is used. Otherwise, a QueuedConnection
is used. –
Cradle Qt::QueuedConnection
? Even if two threads share some data (that both may read or write)? Or when thread A
pass some data through arguments of a signal that is connected to a slot in thread B
? –
Kathykathye QueuedConnection
allows users from many threads to invoke slots on a QObject without having to worry about whether or not that object's methods are re-entrant (because the event loop serializes the invocations). Does that make sense? –
Cradle Qt::QueuedConnection
. –
Kathykathye in addition to Jacob Robbins answer:
the statement "You won't see much of a difference unless you're working with objects having different thread affinities" is wrong;
emitting a signal to a direct connection within the same thread will execute the slot immediately, just like a simple function call.
emitting a signal to a queued connection within the same thread will enqueue the call into the threads event loop, thus the execution will always happen delayed.
Jacob's answer is awesome. I'd just like to add a comparative example to Embedded Programming.
Coming from an embedded RTOS/ISR background, it was helpful to see the similarities in Qt's DirectConnection to Preemptive behavior of the ISRs and Qt's QueuedConnection to Queued Messages in an RTOS between tasks.
Side note: Coming from an Embedded background, it's difficult for me to not define the behavior in the programming. I never leave the argument as Auto, but that is just a personal opinion. I prefer everything to be explicitly written, and yes that gets difficult at times!
© 2022 - 2024 — McMap. All rights reserved.