QT核心 生存執行緒及事件迴圈

2021-10-22 04:03:32 字數 3325 閱讀 6281

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...