最近在使用qt的多執行緒的時候,遇到了乙個問題:如何在子執行緒中操作ui主線程的控制項呢?比如我子執行緒中接收到串列埠的資料變化後,需要更新介面的lcdnumber的數字,但子執行緒又不能直接操作ui控制項。
為此我想了兩個辦法:1. 利用全域性變數 2. 利用訊號和槽
方法1很簡單,但是實時性成了問題,雖然我可以通過定時器定時更新資料,但我實際操作時因為東一行**,西一行**,本來就夠亂的,結果最後抓狂了;
方法2的概念就很清晰,而且實時性很高,不用我操心。
這時候使用的訊號與槽肯定不能是qt本身自帶的了,不符合我們的期望,下面就對自定義訊號與槽進行簡單學習:
signal - 訊號;slot - 槽;emit - 發射訊號;connect - 關聯訊號與槽
其中 slot 就像是我們玩的微控制器中的中斷服務函式,但是qt裡面支援擴充套件「中斷」,所以 connect 的作用就是將中斷事件和中斷服務函式關聯起來。
宣告訊號函式
宣告槽函式
定義槽函式
關聯訊號與槽
發射訊號
槽函式工作
在你子執行緒(發射訊號的類)所在類(.**件)中新增這麼一段:
signals:
void fps_isupdated(int);
這裡 fps_isupdated 函式帶了個引數型別 int,這可不是我寫漏了,只需要資料型別即可,當然你也可以寫多個,不過槽只能接收1個引數,也就是說只能傳1個值。如果你的函式不帶int,那就是不傳值,只是乙個單純的訊號。
地上有張毛爺爺,你也得要有手來撿吧。相應的我們需要有個函式,即我們上面說到的中斷服務函式。
由於 ui 控制項的操作需要在介面類中,所以在介面類的定義中新增如下:
private slots:
void fps_update(int);
發過來的數值我們也要用一樣的引數接收,兩個引數型別一定要一樣哦~
這裡就是來寫中斷服務函式啦,寫上你要做的事情即可:
void module_serialport::fps_update(int fps)
這裡的函式名有些不同,:: 前面是類,表明我的函式是屬於這個類的。這裡這個類是我的 ui 介面,所以我要操作控制項就要在這個類下面。另外函式的引數變成了 int fps,這個fps隨便取名都可以,只是代表傳過來的數值罷了。
不關聯起來你的中斷服務函式怎麼知道什麼時候運作呢,訊號發出來可是誰都能收到的。
舉個例子:你正在家門口和小夥伴們愉快地玩耍,這時候你媽大喊一聲「吃飯了」,母親的呼喚你和你的小夥伴們都聽見了,但是只有你回家去吃飯了。
emmm……所以,懂了嗎?
connect(my1, signal(fps_isupdated(int)), this, slot(fps_update(int)));
這裡地 my1 是指訊號來自 my1這個類,this表示槽來自當前類,也就是你這句話放的地方所屬的類,這裡我把關聯放在ui 的初始化中了,所以自然就是表示 ui 類咯。
在你要發射訊號地位置按照這麼來寫就可以了:
emit fps_isupdated(fps);
這裡地 fps 是我要更新地變數,這裡將這個變數傳出去。
最後一步就是正常執行啦,到此結束,打完收工!
訊號與槽是qt的精髓,我們一定要好好利用,實際上使用起來也不是很難,把他想成微控制器中的中斷就好理解啦
拜~ヾ(•ω•`)o
Qt5訊號槽傳遞自定義資料
本文介紹qt5傳遞自定義資料,非同步處理請求,如下 include 介面命令資料結構 typedef struct cmdrequest cmdrequest 命令處理結果資料結構 typedef struct rstresponse rstresponse 通過槽函式接收命令資料,非同步處理結果後...
QT5 訊號與槽
前言 訊號與槽是qt的精華所在,也是他區分於其他軟體的關鍵地方,所以我們學習qt肯定無法繞過這一核心 當物件內部狀態發生改變,訊號就被反射,只有定義了這個訊號的類和他的子類才能發射這個訊號 訊號的宣告是在標頭檔案中進行的,qt的signals關鍵字指出進入了訊號宣告區,隨後即可宣告自己的訊號。訊號由...
Qt自定義訊號槽
qt自定義訊號槽,在控制台程式中實現 qt5 如下 qt5 include news h class news public qobject void send signals void new const qstring name private qstring m name reader.h i...