Qt中連線到同一signal的多個slots的執行順序問題
-
in the order they have been connected
起源
前些天忘記在哪兒討論過這個問題,今天在csdn又看到有網友問這個問題,而其他網友卻無一例外的給出了“無序”這個答案。
Manual
Qt的問題,當manual中有明確文字說明時,我們應該以Qt的manual為準:
http://doc.qt.nokia.com/4.8/signalsandslots.html
If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.
或者http://doc.qt.nokia.com/4.8/qobject.html
If a signal is connected to several slots, the slots are activated in the same order as the order the connection was made, when the signal is emitted.
恩,說的很明確,各個槽按照被connect的順序被執行【注意,在佇列模式時,是指相應的事件被post,仍不保證槽被按照該順序執行】。
可是,為什麼很多人認為是無序呢?(除了前面提及的,還有什麼其他因素麼?)
翻翻Qt4.5以及該版本之前的manual,可以看到
http://doc.qt.nokia.com/4.5/signalsandslots.html
If several slots are connected to one signal, the slots will be executed one after the other, in an arbitrary order, when the signal is emitted.
以及http://doc.qt.nokia.com/4.5/qobject.html
If a signal is connected to several slots, the slots are activated in an arbitrary order when the signal is emitted.
網路上以及書籍中的大部分資料都是Qt4.6之前的,故爾 ...
原始碼
恩,嘗試看過元物件系統這部分原始碼的網友對這部分不會覺得陌生。如果沒看過,可以瞅瞅這個Qt Meta Object system 學習(三)
- QObject::connect() 最終將 訊號和槽的索引值放置到一個Connection列表中
QObjectPrivate::Connection *c = new QObjectPrivate::Connection; c->sender = s; c->receiver = r; c->method = method_index; c->connectionType = type; c->argumentTypes = types; c->nextConnectionList = 0; QObjectPrivate::get(s)->addConnection(signal_index, c);
-
訊號的發射,就是藉助QMetaObject::activate() 來依次處理前面那個Connection列表總的項
do { QObjectPrivate::Connection *c = connectionLists->at(signal_index).first; if (!c) continue; // We need to check against last here to ensure that signals added // during the signal emission are not emitted in this emission. QObjectPrivate::Connection *last = connectionLists->at(signal_index).last; do { if (!c->receiver) continue; QObject * const receiver = c->receiver;
在該過程中:
- 如果是直接連線,則通過 QMetaObject::metacall() 直接呼叫
- 如果是佇列連線,則post一個QMetaCallEvent事件,稍後通過事件派發,該事件的處理函式負責通過 QMetaObject::metacall() 呼叫相應的槽函式【注意,小心此時槽函式的執行順序】
注意:此處的程式碼片段是Qt4的,而Qt5.0 中由於引入了新式的訊號和槽語法,對應部分原始碼有較大變化。
參考
相關文章
- sql中的or與and的執行順序問題SQL
- SQL中rownum和order by的執行順序的問題SQL
- SQL語句中的AND和OR執行順序問題SQL
- 關於defer執行順序問題
- 同一個元素中有多個class,優先順序
- Qt 中的多執行緒QT執行緒
- C++輸出流cout的執行順序問題C++
- 【Oracle】where條件執行順序(上篇的問題延伸)Oracle
- GROUPBY 和開窗函式執行順序的問題函式
- unittest.TestCase中測試用例執行順序問題
- JavaScript的執行順序JavaScript
- Linux c多執行緒執行順序Linux執行緒
- Laravel 多箇中介軟體的執行順序Laravel
- go fiber: 多個全域性中介軟體的執行順序Go
- Python執行緒專題10:queue、多執行緒按順序執行Python執行緒
- 求助!關於多執行緒連線資料庫的問題執行緒資料庫
- 外連線與連線順序
- 如何使用ReentrantLock的條件變數,讓多個執行緒順序執行?ReentrantLock變數執行緒
- kafka多執行緒順序消費Kafka執行緒
- 從Java到JVM到OS執行緒的優先順序JavaJVM執行緒
- connect by與where條件執行順序問題
- 多個ajax axios請求,呼叫按照順序執行iOS
- 多個執行緒順序列印問題,一網打盡執行緒
- Java for迴圈中語句執行的順序Java
- 多執行緒程式中對資料庫連線使用的疑問執行緒資料庫
- 表的連線順序是否很重要
- 【YashanDB知識庫】繫結引數,同一個sql多個執行計劃的問題SQL
- 一個多執行緒的PushbackInputStream問題執行緒
- js基礎進階–promise和setTimeout執行順序的問題JSPromise
- mysql 中sql語句關鍵字的書寫順序與執行順序MySql
- UITableView停止載入中的動畫的順序問題UIView動畫
- 關於 Promise 的執行順序Promise
- Spring Aop的執行順序Spring
- SQL 語句的執行順序SQL
- CSS規則的執行順序CSS
- Java類的基本執行順序Java
- SQL 執行順序 你懂的SQL
- pipeline的執行順序