原文:http://blog.csdn.net/michealtx/article/details/6866094html
初學Qt,用了Qt自帶的事件,而後想怎麼才能定義本身的事件呢?又如何使用自定義事件呢?看了篇文章,說先要子類化QEvent,而後定義本身的QEvent::Type,而後重寫QWidget::event()函數,而後就能夠調用QCoreApplication::sendEvent()或者QCoreApplication:;postEvent()發送事件就行了。但我比較笨,仍是雲山霧罩,不知道怎麼下手。java
怎麼子類化QEvent?在哪裏定義本身的QEvent::Type?在哪裏重寫QWidget::event()函數?在哪裏調用QCoreApplication::sendEvent()或者QCoreApplication:;postEvent()發送事件?函數
在百度裏搜索開了篇文章對我有啓發http://bluemask.net/p/1215/ ,在google中搜索how to subclass QEvent也搜到一篇對我有啓發的http://www.java2s.com/Code/Cpp/Qt/SubclassQEvent.htm 。(google的英文搜索真不錯!)post
後來我就想,那Qt的發明人是怎麼定義事件的呢?其實站在Qt發明人的角度,QEvent就是他們的「自定義事件」!Ok!這就好辦了!看看Qt發明人怎麼定義的QEvent,看看他們怎麼用本身定義的QEvent,不就回答了文章開頭的倆問題了嘛!O(∩_∩)O~ui
我把整個過程總結爲「長官定義事件」----->「信使傳遞事件」---->「軍隊接收並響應事件」。google
我經過Qt Assistant查找那些與事件相關的類,總結以下:spa
QEvent的任務就是定義一些事件類型Type,它們都定義在了一個enum裏。這就是教程中告訴咱們的要子類化QEvent,派生出MyEvent,而後在MyEvent中定義事件類型QEvent::Type。.net
咱們子類化的時候模仿一個QEvent就行了,並且是繼承,好些都不用子類作了,看一下QEvent類中的成員變量和成員函數,就這些東西:htm
好了,咱們經過子類化QEvent,把派生出來的MyEvent看作長官,它定義了具體某個事件。下面看誰是信使。blog
咱們看看QCoreApplication中定義的一些函數,這些函數就是咱們常常遇到的那些與傳遞事件和過濾事件有關的函數,見下圖:
Public Functions:
因此,到這裏咱們就能夠明確了,你要用QCoreApplication的static public類型的函數入sendEvent或postEvent函數來傳遞送信,要注意:當使用sendEvent時,你的事件要在棧上創建,sendEvent會直接調用notify把事件傳遞給士兵,不走事件隊列;而用postEvent時,你的事件要在堆上創建,即要用new來建立,postEvent會把你的事件追加進事件隊列(詳細過程請看http://blog.csdn.net/michealtx/article/details/6865891)。你還能夠經過重載notify來影響送信過程。
咱們看看QWidget中與事件有關的成員:
看到了嗎?這些就是event handler,即事件處理函數,這是幹活的那幫人。裏面有咱們熟悉的mousePressEvent()、keyPressEvent()等經常使用的事件處理函數,它們都是protected virtual 類型的,能夠重載。因此呀,咱們能夠子類化QWidget,從而繼承獲得好些個event handler,固然也能夠本身定義event handler!至關於本身創造士兵來響應事件。經過山寨QWidget,就能夠創造本身的軍隊!
還有一點就是,當事件到達軍隊的時候,要先審查再分發,審查就是要通過事件過濾,分發就是經過對通過審查的事件進行判斷再把它分給那個相應的士兵這就又涉及到一個類QObject,這是Qt的萬類之母,這個類中有兩個函數一個是eventFilter(),另外一個是event()。要先子類化QObject來建立一個監控者,這個監控者重載eventFilter(),來爲軍隊過濾事件。而後還要在軍隊(QWidget)經過調用installEventFilter ( QObject * filterObj )來安裝過濾器,參數中的filterOb即爲監控者。最後在軍隊(QWidget)中重載event()來分發事件,把事件分給對應會幹這個活的士兵(event handler)。
好了,我理解的大致過程就是這樣,我是Qt新手,可能有錯的地方,但願路過的大牛能給與指正,我將不勝感激!
什麼話也不如來個例程給力!:
我創建的是Qt Console Application,工程叫MyEvent,下面是main.cpp中的代碼:
運行結果: