問題描述
我在處理 Qt 信號時遇到問題.
I'm having trouble with Qt signals.
我不明白 DirectConnection
和 QueuedConnection
是如何工作的?
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).
推薦答案
除非您使用具有不同線程親緣關系的對象,否則您不會看到太大差異.假設您有 QObjects A
和 B
并且它們都附加到不同的線程.A
有一個名為 somethingChanged()
的信號,B
有一個名為 handleChange()
的槽.
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()
.
如果您使用直接連接
connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection );
方法 handleChange()
將實際運行在 A
的線程中.基本上,就好像發出信號直接"調用插槽方法一樣.如果 B::handleChange()
不是線程安全的,這可能會導致一些(難以定位)錯誤.至少,您錯過了額外線程的好處.
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.
如果您將連接方法更改為 Qt::QueuedConnection
(或者,在這種情況下,讓 Qt 決定使用哪種方法),事情會變得更有趣.假設 B
的線程正在運行一個事件循環,發出信號將向 B
的事件循環發送一個事件.事件循環對事件進行排隊,并最終在控制權返回給它時調用 slot 方法(它是事件循環).這使得處理 Qt 中線程之間的通信變得非常容易(再次假設您的線程正在運行它們自己的本地事件循環).您不必擔心鎖定等問題,因為事件循環會序列化槽調用.
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.
注意:如果您不知道如何更改 QObject 的線程關聯,請查看 QObject::moveToThread
.這應該會讓你開始.
Note: If you don't know how to change a QObject's thread affinity, look into QObject::moveToThread
. That should get you started.
編輯
我應該澄清一下我的開場白.如果您指定一個排隊連接,它確實會有所不同——即使對于同一線程上的兩個對象.該事件仍然發布到線程的事件循環.因此,方法調用仍然是異步的,這意味著它可以以不可預測的方式延遲(取決于循環可能需要處理的任何其他事件).但是,如果不指定連接方法,同一個線程上的對象之間的連接會自動使用直接方法(至少在Qt 4.8中是這樣).
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).
這篇關于Qt 信號(QueuedConnection 和 DirectConnection)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!