Qt入門(8)——事件和事件過濾器
在Qt裡,一個事件是繼承自QEvent的物件。事件通過呼叫QObject::event(),被髮送到繼承自 QObject 的物件。事件傳送就是一個事件已經產生,由 QEvent正好去表達,且QObject 需要去迴應。多數事件針對 QWidget和他的子類的,此外還有些不和圖形相關的重要事件,比如,套接字啟用,——某種被用於QSocketNotifier運作的事件。
某些事件來自視窗系統,如QMouseEvent,某些來自其他源頭,如QTimerEvent,而某些來自應用程式。Qt一視同仁,因此像通常一樣,你可以準確地傳送事件,這和Qt自己的事件迴圈所作的方式一樣。
多數事件型別具有特定的類,最常見的QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent和QCloseEvent。有很多別的,差不多40種左右,但大都是相當零碎。
每個類派生自QEvent且新增事件特定的函式;例如,QResizeEvent。在QResizeEvent中,就被加入了QResizeEvent::size()和QResizeEvent::oldSize()。
某些類支援多種事件型別。QMouseEvent支援滑鼠移動、按壓、粘滯按壓、拖拽、點選、右按壓,等等。
因為程式需要在多變且複雜的方式下作用,Qt的事件派發機制就是靈活的。QApplication::notify() 的文件扼要地敘述其整個來龍去脈,我們揭示在這裡的內容滿足99%的應用。
對於事件去被派發的正常的辦法是呼叫一個虛擬函式。如,QPaintEvent通過呼叫QWidget::paintEvent()被使用。這個虛擬函式負責引起適當的響應,一般是重畫視窗部件。
有時,並不存在一個特定事件函式,或者特定事件功能不足。最普通的例如按下tab鍵。正常情況下,被QWidget看成是去移動 鍵盤焦點,但少數視窗部件 需要自行解釋。
這些物件能重新實現QObject::event(),按常規事件處理,以及要麼在通常的處理之前,或之後處理,或完全重寫。一個與眾不同的的視窗部件,它解釋了tab,也含有一個該應用特定的可能包含的自定製事件:
bool MyClass:event( QEvent * e ) {
if ( e->type() == QEvent::KeyPress ) {
QKeyEvent * ke = (QKeyEvent*) e;
if ( ke->key() == Key_Tab ) {
// 這裡是特定的tab處理
k->accept();
return TRUE;
}
} else if ( e->type() >= QEvent::User ) {
QCustomEvent * c = (QCustomEvent*) e;
// 這裡是自定義事件處理
return TRUE;
}
QWidget::event( e );
}
更一般的,一個物件需要去考慮其它的事件。Qt用QObject::installEventFilter()支援這個目的(相應的有移除)。如,對話方塊通常要為某些視窗部件去過濾按鍵,比如,去修改Return鍵的處理。
一個事件過濾器在目標物件處理之前得以去處理事件。過濾器的QObject::eventFilter()實現被呼叫,它可以接受或丟棄過濾,也可容許或拒絕進一步去處理事件。如果所有的事件過濾器允許進一步的處理事件,事件自己就被送達目標物件。如果它們之一停止處理,目標和任何後面的事件過濾器根本就對該事件一無所知了。
整個應用程式中過濾所有的事件也是可能的,通過在QApplication上安裝一個事件過濾器。這裡有QToolTip為了處理全部滑鼠和鍵盤行為的實作。這個功能相當強大,但其在整個應用中也拖慢了每單個事件的派送,因此最好避免這種應用方式。
全域性事件過濾器在物件特定的過濾器前被呼叫。
許多應用程式都要建立和傳送他們自己的事件。
建立一種內建型別的事件是非常簡單的:建立一個相應的型別的物件,然後呼叫QApplication::sendEvent()或者QApplication::postEvent()。
sendEvent() 立即處理事件——當sendEvent() 返回,(事件過濾器和)物件已經處理過事件了。對於很多事件類,呼叫isAccepted()函式,他告知你該事件能否被目前呼叫的處理者所接受或者拒絕。
postEvent()投送事件於一個佇列,以使能延遲派發。在下次Qt的主事件迴圈執行,他派發全部事件,帶有些優化。舉例,若有數個resize事件,它們就被壓縮到一個。對於paint事件同樣如此:QWidget::update()呼叫 postEvent(),最小化閃屏和避免多次重畫,以增加速度。
postEvent()在物件初始化期間常常被使用,因為在物件完成初始化後,投送的訊息會被很快派發。
去建立一個自定義型別的事件,你需要定義一個事件號,其必須大於QEvent::User,可能你也需要從QCustomEvent去派生,為了傳遞有關你的自定義事件的特性。看QCustomEvent的文件瞭解細節。
某些事件來自視窗系統,如QMouseEvent,某些來自其他源頭,如QTimerEvent,而某些來自應用程式。Qt一視同仁,因此像通常一樣,你可以準確地傳送事件,這和Qt自己的事件迴圈所作的方式一樣。
多數事件型別具有特定的類,最常見的QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent和QCloseEvent。有很多別的,差不多40種左右,但大都是相當零碎。
每個類派生自QEvent且新增事件特定的函式;例如,QResizeEvent。在QResizeEvent中,就被加入了QResizeEvent::size()和QResizeEvent::oldSize()。
某些類支援多種事件型別。QMouseEvent支援滑鼠移動、按壓、粘滯按壓、拖拽、點選、右按壓,等等。
因為程式需要在多變且複雜的方式下作用,Qt的事件派發機制就是靈活的。QApplication::notify() 的文件扼要地敘述其整個來龍去脈,我們揭示在這裡的內容滿足99%的應用。
對於事件去被派發的正常的辦法是呼叫一個虛擬函式。如,QPaintEvent通過呼叫QWidget::paintEvent()被使用。這個虛擬函式負責引起適當的響應,一般是重畫視窗部件。
有時,並不存在一個特定事件函式,或者特定事件功能不足。最普通的例如按下tab鍵。正常情況下,被QWidget看成是去移動 鍵盤焦點,但少數視窗部件 需要自行解釋。
這些物件能重新實現QObject::event(),按常規事件處理,以及要麼在通常的處理之前,或之後處理,或完全重寫。一個與眾不同的的視窗部件,它解釋了tab,也含有一個該應用特定的可能包含的自定製事件:
bool MyClass:event( QEvent * e ) {
if ( e->type() == QEvent::KeyPress ) {
QKeyEvent * ke = (QKeyEvent*) e;
if ( ke->key() == Key_Tab ) {
// 這裡是特定的tab處理
k->accept();
return TRUE;
}
} else if ( e->type() >= QEvent::User ) {
QCustomEvent * c = (QCustomEvent*) e;
// 這裡是自定義事件處理
return TRUE;
}
QWidget::event( e );
}
更一般的,一個物件需要去考慮其它的事件。Qt用QObject::installEventFilter()支援這個目的(相應的有移除)。如,對話方塊通常要為某些視窗部件去過濾按鍵,比如,去修改Return鍵的處理。
一個事件過濾器在目標物件處理之前得以去處理事件。過濾器的QObject::eventFilter()實現被呼叫,它可以接受或丟棄過濾,也可容許或拒絕進一步去處理事件。如果所有的事件過濾器允許進一步的處理事件,事件自己就被送達目標物件。如果它們之一停止處理,目標和任何後面的事件過濾器根本就對該事件一無所知了。
整個應用程式中過濾所有的事件也是可能的,通過在QApplication上安裝一個事件過濾器。這裡有QToolTip為了處理全部滑鼠和鍵盤行為的實作。這個功能相當強大,但其在整個應用中也拖慢了每單個事件的派送,因此最好避免這種應用方式。
全域性事件過濾器在物件特定的過濾器前被呼叫。
許多應用程式都要建立和傳送他們自己的事件。
建立一種內建型別的事件是非常簡單的:建立一個相應的型別的物件,然後呼叫QApplication::sendEvent()或者QApplication::postEvent()。
sendEvent() 立即處理事件——當sendEvent() 返回,(事件過濾器和)物件已經處理過事件了。對於很多事件類,呼叫isAccepted()函式,他告知你該事件能否被目前呼叫的處理者所接受或者拒絕。
postEvent()投送事件於一個佇列,以使能延遲派發。在下次Qt的主事件迴圈執行,他派發全部事件,帶有些優化。舉例,若有數個resize事件,它們就被壓縮到一個。對於paint事件同樣如此:QWidget::update()呼叫 postEvent(),最小化閃屏和避免多次重畫,以增加速度。
postEvent()在物件初始化期間常常被使用,因為在物件完成初始化後,投送的訊息會被很快派發。
去建立一個自定義型別的事件,你需要定義一個事件號,其必須大於QEvent::User,可能你也需要從QCustomEvent去派生,為了傳遞有關你的自定義事件的特性。看QCustomEvent的文件瞭解細節。
相關文章
- Qt事件過濾器的使用QT事件過濾器
- Qt 事件傳遞流程-事件處理器|事件分發器|事件過濾器QT事件過濾器
- Vue入門指南-04 事件機制和事件/按鍵修飾符和過濾器及監聽屬性(快速上手vue)Vue事件過濾器
- EasyUI datagrid 過濾事件段UI事件
- Spring Cloud Gateway ---GatewayFilter過濾器、過濾器工廠(入門)SpringCloudGatewayFilter過濾器
- 事件和事件監聽器事件
- MySQL入門--EVENT(事件)MySql事件
- qt事件機制QT事件
- vue 基礎入門筆記 07:過濾器Vue筆記過濾器
- JavaScript入門⑧-事件總結大全JavaScript事件
- javascript快速入門17--事件JavaScript事件
- JavaScript學習11:事件入門JavaScript事件
- vue從入門到進階:過濾器filters(五)Vue過濾器Filter
- Omi 入坑指南 Third field 事件入門事件
- Qt 事件機制 學習QT事件
- Qt中的焦點事件QT事件
- 從入門到放棄 - 事件溯源事件
- Vue入門—事件與方法詳解Vue事件
- 監聽器和過濾器過濾器
- 過濾器入門看這一篇就夠了過濾器
- JS事件(事件冒泡和事件捕獲)JS事件
- React 事件和 Dom 事件React事件
- onscroll 事件和onScrollCapture事件事件APT
- 極簡 Node.js 入門 - 2.2 事件Node.js事件
- 協同過濾演算法——入門演算法
- QT入門QT
- 事件模型和事件委託事件模型
- 事件冒泡 和 事件捕獲事件
- 常見的過濾場景:使用者在文字框輸入過濾引數,捕獲TextChanged事件,執行ICollectionView.Refresh( ).事件View
- 過濾Servlet--過濾器Servlet過濾器
- [譯] setState() 門事件事件
- Qt入門(3)——訊號和槽QT
- Flask入門資料庫的查詢集與過濾器(十一)Flask資料庫過濾器
- 透過事件風暴和DDD建立微服務時優先考慮事件事件微服務
- Spring 過濾器和攔截器Spring過濾器
- 過濾器和監聽器總結過濾器
- JavaScript事件冒泡、事件捕獲和阻止預設事件JavaScript事件
- JS事件流和事件委託JS事件