QT 事件的總結

2021-08-08 10:05:40 字數 2758 閱讀 7321

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()函式是所有物件的事件入口,qobjectqwidget中的實現,預設是把事件傳遞給特定的事件處理函式。

在特定物件上面安裝事件過濾器。該過濾器僅過濾該物件接收到的事件。

為了進一步了解這幾個層次的事件處理方式的呼叫順序,我們可以編寫乙個測試**:

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