qt最核心的兩個東西莫過於元物件和事件迴圈了,這兩個特性是日常程式設計中的兩大利器,理解和使用好這兩個特性對寫qt程式有非常大的幫助,就比如qt乙個創新功能點訊號槽就是利用這兩個特性實現(後面可能會單獨講解),我們這裡率先理解一下事件迴圈,畢竟元物件裡面有個東西也是利用事件迴圈來實現的(後面會說)。
生存執行緒
首先,我們要知道生存執行緒的概念,也正是因為qobject的生存執行緒問題,導致qt的多執行緒變複雜了,同時功能也更強大了。
大家在網上搜qt多執行緒的話一定能接觸到的一種方式:
qobject o;
qthread t;
t.start()
;o.movetothread
(&t)
;
上面movetothread就是改變物件o的生存執行緒,該方法的引數為目標執行緒。下面一行一行**解析:
qobject o;
構造乙個qobject型別的棧物件o(這裡new堆物件也是一樣),在qobject構造時會自動獲取當前執行緒(qthread::currentthread,當然qt內部可能不是呼叫的這個方法,但基本等價),獲取到的當前執行緒即為該物件預設生存執行緒。也即是說,乙個繼承至qobject的類,它在哪個執行緒中構造,它的生存執行緒就是哪個。那麼可以得出以下結論:
/*!
* \brief threadtest繼承至qthread
* 由於run函式執行在子執行緒,所以物件o預設生存執行緒和該子執行緒一樣,所以下面movetothread方法無意義
* 所以下面三個qdebug語句的輸出資料一樣
*/void threadtest::
run(
)
qthread t;
構造乙個執行緒,但要注意,因為qthread也是繼承至qobject,所以它也有生存執行緒,但是它的生存執行緒對它的run方法的執行執行緒不會造成影響。
t.start();
啟動執行緒,qthread的run方法預設有乙個實現,是呼叫它自身的exec方法啟動乙個事件迴圈。
void qthread::
run(
)int qthread::
exec()
locker.
unlock()
; qeventloop eventloop;
int returncode = eventloop.
exec()
; locker.
relock()
; d-
>exited =
false
; d-
>returncode =-1
;return returncode;
}
// 標頭檔案
#pragma once
#include
class
objecttest
:public qobject
;
// cpp檔案
#include
"objecttest.h"
#include
#include
#include
objecttest::
objecttest
(qobject *parent)
:qobject
(parent)
void objecttest::
customevent
(qevent *event)
// 使用這個類,注意: 這裡的m_d變數是乙個屬性,請在合適的地方宣告這個屬性
qdebug()
<<
"main thread:"
<< qthread::
currentthread()
;objecttest *o =
newobjecttest()
;// 構造乙個物件,但是不能指定parent,否則不能使用movetothread
// 向物件中拋乙個事件,注意: 這裡的type必須大於等於qevent::user,否則不能被customevent接收到。對於小於qevent::user的事件會被最原始event方法接收
>
postevent
(o,new
qevent
(static_cast
(qevent::user +1)
));// 讓物件執行之前丟擲的事件,否則該事件還未執行時使用movetothread方法會導致之前未執行的事件也在新執行緒中執行,注意: movetothread之後不能再用這個方法
>
sendpostedevents
(o);
m_t =
newqthread
(this);
m_t-
>
start()
;qdebug()
<<
"new thread:"
<< m_t;
o->
movetothread
(m_t)
;>
postevent
(o,new
qevent
(static_cast
(qevent::user +1)
));
// 執行輸出結果
main thread:
qthread
(0x16dfd0bad20
)event type: qevent::
type
(1001
)objecttest thread:
qthread
(0x16dfd0bad20
)cur thread:
qthread
(0x16dfd0bad20
)new thread:
qthread
(0x16dfd0fb620
)event type: qevent::
type
(1001
)objecttest thread:
qthread
(0x16dfd0fb620
)cur thread:
qthread
(0x16dfd0fb620
)
總結而言: 所謂生存執行緒就是qobject及其子類的event和衍生事件方法的執行執行緒。
剩下的東西單開一章吧,否則這篇文章又臭又長。
Qt 多執行緒之逐執行緒事件迴圈
從別的執行緒中訪問qobject子類 qobject和所有它的子類是非執行緒安全的。這包括整個的事件投遞系統。需要牢記的是,當你正從別的執行緒中訪問物件時,事件迴圈可以向你的qobject子類投遞事件。假如你呼叫乙個不生存在當前執行緒中的qobject子類的函式時,你必須用mutex來保護qobje...
QT事件迴圈
什麼是自發事件?哪些型別的事件可以被propagated 或compressed?posting and sending 事件之間有何不同?什麼時候應該呼叫 accept 或是ignore 如果這些問題你還不是很了解,那麼繼續看下去。事件起源 定製事件型別 到現在為至,我們所說的內容不僅僅適用於ke...
qt按鈕功能迴圈觸發 Qt事件迴圈處理
qt事件迴圈處理 這會造成什麼現象呢?網路請求不可用 qnetworkaccessmanager get 不可用,即你呼叫了 get 無法收到 finished 訊號 qtcpsocket connecttohost 不可用,即你呼叫了 connecttohost 無法連線到主機 呼叫 qtcpso...