看了下Qt的幫助文檔,發現connect函數最后還有一個缺省參數.
connect函數原型是這樣的:
QMetaObject::Connection QObject::connect(const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection)
最后的ConnectionType是一個缺省的參數,默認為自動連接方式,我們來看一下這個參數有哪些值
Qt supports these signal-slot connection types:
Auto Connection (default) If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection. Otherwise, the behavior is the same as the Queued Connection."
Direct Connection The slot is invoked immediately, when the signal is emitted. The slot is executed in the emitter's thread, which is not necessarily the receiver's thread.
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.
Note: Using this type to connect objects in the same thread will cause deadlock.
Unique Connection The behavior is the same as the Auto Connection, but the connection is made only if it does not duplicate an existing connection. i.e., if the same signal is already connected to the same slot for the same pair of objects, then the connection is not made and connect() returns false
可以看出一共是5個值:自動、直接、隊列、阻塞隊列、唯一。
我們先看下 直接和隊列。
直接連接的大概意思是:信號一旦發射,槽立即執行,並且槽是在信號發射的線程中執行的。
隊列連接的大概意思是:信號發射后當事件循環返回到接收線程時槽函數就執行了,也就是說這種連接方式不是立即觸發槽函數的,而是要排隊等的,並且是在槽函數的線程中執行。
再來看看 自動和阻塞隊列方式
自動連接的大概意思是:信號發射對象如果和槽的執行對象在同一個線程,那么將是直連方式,否則就是隊列方式。
阻塞隊列方式:在槽函數返回之前槽函數所在的線程都是阻塞的。
唯一方式:和直連相同,但是只能一對一連接。
Qt幫助文檔中提醒到:Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.
即跨線程調QObject對象是不安全的。
Call qRegisterMetaType() to register the data type before you establish the connection。
另外信號槽的參數必須是注冊的MetaType,所以當你使用自定義的類型或者 沒有注冊的類型,都要調用qRegisterMetaType()進行注冊,因為Qt需要保存你的參數。