Qt的事件和與Widget跨執行緒互動

2021-06-15 00:11:36 字數 1385 閱讀 6741

一般gui的程式的模型總有至少兩個主要執行緒,乙個是介面的主事件迴圈所在的執行緒,另乙個是處理工作任務的執行緒,工作執行緒看不見,在後台處理事務產生資料,然後顯示在介面上。例如乙個即時通訊客戶端,主介面顯示好友列表,工作執行緒接受來自網路的訊息,收到訊息後,要通知介面,將對應的好友的頭像閃爍顯示。這就要跨執行緒

記得c#中有委託delegate,有invokerequired屬性判斷是否同執行緒操作,有invoke來呼叫跨執行緒的委託。初學pyside,遇到同樣的問題,看了半天文件,發現沒有和c#類似的手段。但是,反倒可以用更有條理的方式來處理這樣的跨執行緒呼叫請求,那就是事件。

qevent是所有qt事件的基類,建構函式只接受乙個引數,那就是qevent.type型別的事件型別引數,如果是內建的事件型別,可以直接使用已定義的型別,例如qevent.close,它本質是乙個int整數。如果要定義乙個自己的事件,就需要乙個這樣的數字,而且和已有的所有事件型別不重複。

首先,使用qevent.registereventtype這個靜態方法來註冊乙個自己的型別,自定義的型別的值的返回是(qevent.user, qevent.usermax)之間的乙個數字,呼叫registereventtype時可以指定這樣乙個自己的數字,也可以不指定,由其自動分配乙個數字。例如:

event_incoming_message = qevent.registereventtype(qevent.user + 0x01)
有了這個自己的型別,然後就是構建乙個自己的事件類:

class incomingmessageevent(qevent):

def __init__(self, msg):

super(incomingmessageevent, self).__init__(

qevent.type(event_incoming_message)

)self.msg = msg

事件是投遞完成,那麼在qdialog中還得處理這個事件,不然dlg就要當spam來處理了... 

所有qt的widget處理事件,都是由它的event方法來進行,所以只需要在自己的widget中實現乙個自己的event方法,該方法接受單個qevent型別的引數。

class mainframe(qdialog):

# ......

def event(self, evt):

if evt.type() == event_incoming_message:

if hasattr(evt, 'msg'):

msg = evt.msg

self.show_incoming_message(msg) # 在介面顯示該訊息

return super(mainframe, self).event(evt)

這時就可以安全的處理要顯示的內容了。

Qt 的事件監聽和事件過濾

qt 產品級的開發專案中經常會用到一些自定義控制項,從而達到一些可定製化的效果,這時候往往需要重寫它的監聽事件,滿足產品的需求。這裡用乙個簡單的例子記錄一下思路 新建乙個diylabel 繼承 qlabel 重寫enterevent 和 mousepressevent 例子 diylabel 的實現...

Qt事件的接收和忽略

qt的事件是依次分發的,一般由系統自動處理。如果我們需要手動處理事件,需要重寫相關的事件函式。在重寫函式中,處理完我們所需的操作之後,有兩種選擇,一種是讓事件繼續傳遞,即忽略該事件,另一種是 不讓該事件繼續傳遞即接收該事件。下面是簡單的示例 void mypushbutton mousepresse...

Qt 事件的接收和忽略

我們可以把qt的事件傳遞看成鏈狀 如果子類沒有處理這個事件,就會繼續向其父類傳遞 1.新建乙個mybutton類,將其基類改為qpushbutton.2.在ui中新建乙個push button控制項,並將其提公升為mybutton.3.在mybutton.h中增加滑鼠按下事件.ifndef mybu...