Qt之事件處理機制

2022-04-22 13:42:44 字數 3272 閱讀 9322

qt程式是事件驅動的, 程式的每個動作都是由內部某個事件所觸發。qt事件的發生和處理成為程式執行的主線,存在於程式整個生命週期。

常見的qt事件型別如下:

鍵盤事件: 按鍵按下和鬆開

滑鼠事件: 滑鼠移動,滑鼠按鍵的按下和鬆開

拖放事件: 用滑鼠進行拖放

滾輪事件: 滑鼠滾輪滾動

繪屏事件: 重繪螢幕的某些部分

定時事件: 定時器到時

焦點事件: 鍵盤焦點移動

進入和離開事件: 滑鼠移入widget之內,或是移出

移動事件: widget的位置改變

大小改變事件: widget的大小改變

顯示和隱藏事件: widget顯示和隱藏

視窗事件: 視窗是否為當前視窗

qt將系統產生的訊息轉化為qt事件,qt事件被封裝為物件,所有的qt事件均繼承抽象類qevent,用於描述程式內部或外部發生的動作,任意的qobject物件都具備處理qt事件的能力。

作業系統將獲取的事件,比如滑鼠按鍵,鍵盤按鍵等keypressevent,keyreleaseevent,mousepressevent,mousereleaseevent事件, 放入系統的訊息佇列中,qt事件迴圈的時候讀取訊息佇列中的訊息,轉化為qevent並被分發到相應的qwidget物件,相應的qwidget中的event(qevent *)進行事件處理會對事件進行處理,event(qevent *)會根據事件型別呼叫不同的事件處理函式,在事件處理函式中傳送qt預定義的訊號,最終呼叫訊號關聯的槽函式。

gui應用程式的事件處理:

a、qt事件產生後會被立即傳送到相應的qwidget物件

b、相應的qwidget中的event(qevent *)進行事件處理

c、event(qevent *)根據事件型別呼叫不同的事件處理函式

d、在事件處理函式中傳送qt預定義的訊號

e、呼叫訊號關聯的槽函式

另一種方式是呼叫sendevent()函式,事件不會放入佇列, 而是直接被派發和處理, qwidget::repaint()函式用的就是阻塞型的。

sendevent()中事件物件的生命期由qt程式管理,支援分配在棧上和堆上的事件物件;postevent()中事件物件的生命期由qt平台管理,只支援分配在堆上的事件物件,事件被處理後由qt平台銷毀。

事件有兩種排程方式,同步和非同步。

事件過濾器是qt中乙個獨特的事件處理機制, 功能強大而且使用起來靈活方便。通過事件過濾器, 可以讓乙個物件偵聽攔截另外乙個物件的事件。事件過濾器實現如下: 在所有qt物件的基類qobject中有乙個型別為qobjectlist的成員變數,名字為eventfilters,當某個qobject(a)給另乙個qobject(b)安裝了事件過濾器後, b會把a的指標儲存在eventfilters中。在b處理事件前,會先去檢查eventfilters列表, 如果非空, 就先呼叫列表中物件的eventfilter()函式。乙個物件可以給多個物件安裝過濾器,乙個物件能同時被安裝多個過濾器, 在事件到達之後, 事件過濾器以安裝次序的反序被呼叫。事件過濾器函式( eventfilter() ) 返回值是bool型, 如果返回true, 則表示事件已經被處理完畢, qt將直接返回, 進行下一事件的處理。如果返回false, 事件將接著被送往剩下的事件過濾器或是目標物件進行處理。

在reciver::event()中, 先檢查有無事件過濾器安裝在reciever上。若有, 則呼叫之。然後根據qevent的型別, 呼叫相應的特定事件處理函式。常見的事件都有特定事件處理函式, 比如:mousepressevent(), focusoutevent(),  resizeevent(), paintevent(), resizeevent()等等。在實際應用中, 經常需要過載特定事件處理函式處理事件。對於不常見的事件, 沒有相對應的特定事件處理函式,如果要處理這些事件, 就需要使用別的辦法, 比如過載event() 函式, 或是安裝事件過濾器。

qt提供了五種不同級別的事件處理和過濾:

a、重寫特定事件處理函式.

最常見的事件處理辦法就是重寫mousepressevent(), keypressevent(), paintevent() 等特定事件處理函式。

b、重寫event()函式.

重寫event()函式時, 需要呼叫父類的event()函式來處理不需要處理或是不清楚如何處理的事件。

return qwidget::event(event);

c、在qt物件上安裝事件過濾器

安裝事件過濾器有兩個步驟: (假設要用a來監視過濾b的事件)

首先呼叫b的installeventfilter( const qoject *obj ), 以a的指標作為引數,所有發往b的事件都將先由a的eventfilter()處理。然後, a要重寫qobject::eventfilter()函式, 在eventfilter() 中對事件進行處理。

class defineevent : public

qevent

qstring data()

private

: qstring m_data;

};

#ifndef widget_h

#define widget_h#include

#include

#include

"stringevent.h

"#include

#include

#include

qwidget

bool

event(qevent*evt)

return qwidget::event

(evt);

}bool eventfilter(qobject* obj, qevent*evt)

return

qwidget::eventfilter(obj, evt);

}~widget()

}; #endif

//widget_h

補充:自定義事件型別可以使用registereventtype

qevent::type imageloadedevent::evtype()

return s_evtype;
}

qt按鍵事件處理機制分析

本為以qt2.3.12作為原始碼進行分析。下面是乙個簡單的顯示乙個按鍵,並將按鍵鏈結到退出操作的程式,本文將一步一步分析,qt是如何實現此操作的。qpushbutton是繼承於qbutton的,我們可以到qbutton.cpp中檢視click 事件是如何產生的。qt2 src widgets qbu...

事件委託處理機制

事件委託處理機制實現了在兩個沒有聯絡的物件之間建立一種事件收發機制,事件傳送方和事件監聽方互相不必知道對方的任何細節,避免物件之間的依賴,降低系統耦合性。直接上 event.h pragma once include using std map ifdef dll export define dll...

android事件處理機制

談到android事件處理,最複雜的就是對touch事件的處理,因為touch事件包括 down,move,up,cancle和多點觸控等多種情況,多點觸控的情況先不討論,因為touch有這麼多的狀態,所以touch相對來說是最難處理的,下面就來討論一下android系統是如何處理touch事件的 ...