qt 的事件是整個 qt 框架的核心機制之一,也比較複雜。說它複雜,更多是因為它涉及到的函式眾多,而處理方法也很多,有時候讓人難以選擇。
qt 中有很多種事件:滑鼠事件、鍵盤事件、大小改變的事件、位置移動的事件等等。如何處理這些事件,實際有兩種選擇:
1. 所有事件對應乙個事件處理函式,在這個事件處理函式中用乙個很大的分支語句進行選擇,其代表作就是 win32 api 的wndproc()
函式:lresult callback wndproc(hwnd hwnd,
uint message,
wparam wparam,
lparam lparam)
在這個函式中,我們需要使用switch
語句,選擇message
引數的型別進行處理,典型**是:
switch(message)
每一種事件對應乙個事件處理函式。qt 就是使用的這麼一種機制:
qt 具有這麼多種事件處理函式,肯定有乙個地方對其進行分發,否則,qt 怎麼知道哪一種事件呼叫哪乙個事件處理函式呢?這個分發的函式,就是event()
。顯然,當qmouseevent
產生之後,event()
函式將其分發給mouseevent()
事件處理器進行處理。
event()
函式會有兩個問題:
event()
函式是乙個 protected 的函式,這意味著我們要想重寫event()
,必須繼承乙個已有的類。試想,我的程式根本不想要滑鼠事件,程式中所有元件都不允許處理滑鼠事件,是不是我得繼承所有元件,一一重寫其event()
函式?protected 函式帶來的另外乙個問題是,如果我基於第三方庫進行開發,而對方沒有提供源**,只有乙個鏈結庫,其它都是封裝好的。我怎麼去繼承這種庫中的元件呢?
event()
函式的確有一定的控制,不過有時候我的需求更嚴格一些:我希望那些元件根本看不到這種事件。event()
函式雖然可以攔截,但其實也是接收到了qmouseevent
物件。我連讓它收都收不到。這樣做的好處是,模擬一種系統根本沒有那個事件的效果,所以其它元件根本不會收到這個事件,也就無需修改自己的事件處理函式。這種需求怎麼辦呢?
事件過濾器可以解決剛剛我們提出的event()
函式的兩點不足:首先,事件過濾器不是 protected 的,因此我們可以向任何qobject
子類安裝事件過濾器;其次,事件過濾器在目標物件接收到事件之前進行處理,如果我們將事件過濾掉,目標物件根本不會見到這個事件。
該函式會將event
傳送給receiver
,也就是呼叫receiver->event(event)
,其返回值就是來自receiver
的事件處理器。注意,這個函式為任意執行緒的任意物件的任意事件呼叫,因此,它不存在事件過濾器的執行緒的問題。不過我們並不推薦這麼做,因為notify()
函式只有乙個,而事件過濾器要靈活得多。
現在我們可以總結一下 qt 的事件處理,實際上是有五個層次:
重寫paintevent()
、mousepressevent()
等事件處理函式。這是最普通、最簡單的形式,同時功能也最簡單。
重寫event()
函式。event()
函式是所有物件的事件入口,qobject
和qwidget
中的實現,預設是把事件傳遞給特定的事件處理函式。
在特定物件上面安裝事件過濾器。該過濾器僅過濾該物件接收到的事件。
為了進一步了解這幾個層次的事件處理方式的呼叫順序,我們可以編寫乙個測試**:
.h 檔案
#ifndef label_h
#define label_h
#include
#include
#include
#include
#include
class label : public qwidget
label(qwidget *parent); // 帶參建構函式
~label();
bool eventfilter(qobject *watched, qevent *event);
protected:
void mousepressevent(qmouseevent *);
bool event(qevent *e);
private:
.cpp檔案
#include "label.h"
label::label(qwidget *parent)
: qwidget(parent)
label::~label()
bool label::eventfilter(qobject *watched, qevent *event)
}return false;
}void label::mousepressevent(qmouseevent *)
bool label::event(qevent *e)
return qwidget::event(e);}
主函式執行之後發現:
因此可以知道,全域性事件過濾器被第乙個呼叫,之後是該物件上面的事件過濾器,其次是event()
函式,最後是特定的事件處理函式。
Qt滑鼠事件總結
滑鼠按下事件void qwidget mousepressevent qmouseevent event elseif event button qt rightbutton elseif event button qt midbutton 滑鼠移動事件void qwidget mousemovee...
Qt的滑鼠事件
qt裡常用的滑鼠事件有mousepressevent mousemoveevent mousereleaseevent mousedoubleclickevent滑鼠事件方法。void mousepressevent qmouseevent e void mousemoveevent qmousee...
Qt 的事件系統
在 qt 裡面,事件就是繼承自抽象 qevent 類的乙個物件,它表示乙個應用內部或者乙個應用需要知道的外部活動的結果。任何乙個繼承自 qobject 的子類例項都可以接收和處理事件。乙個事件發生,qt 會建立乙個能夠合適的描述這個事件的物件,這個物件繼承自 qevent.然後通過呼叫 event ...