qt類 qevent
事件處理過程
事件過濾器 是本文要介紹的內容,我們直接進入內容 。
事件處理流程
:
某個事件發生------>exe
c()迴圈
會接收到這個事件------>
建立乙個事件物件,並將物件傳遞給qobject::event()------>
在qwid
get::event()函式
中,分配給特定的事件處理函式------>
在qbutton
的事件處理函式中em
it(cli
cked訊息
)前面說到了事件的作用,下面來看看我們如何來接收事件 。回憶一下前面的**
,我們在子類中重寫了事件函式,以便讓這些子類按照我們的需要完成某些功能
,就像下面的**:
void my上面的**和前面類似,在滑鼠label::mousepressevent
(qmouseevent * event)
else
}
按下的事件中檢測
,如果按下的是左鍵,做我們的處理工作,如果不是左鍵,則呼叫
父類的函式 。這在某種程度上說,是把事件向上傳
遞給父類去響應,也就是說,我們在子類中「忽略」了這個事件 。
我們可以把qt的事件傳遞看成鏈狀:如果子類沒有處理這個事件,就會繼續向其他類傳遞 。其實,qt的事件物件都有乙個accept()函式
和ignore()函式 。正如它們的名字,前者用來告訴qt,事件處理函式「接收」了這個事件,不要再傳遞;後者則告訴qt,事件處理函式「忽略」了這個事件,需要繼續傳遞,尋找另外的接受者 。在事件處理函式中,可以使用isaccepted()來查詢
這個事件是不是已經被接收了 。
事實上,我們很少使用accept()和ignore()函式,而是想上面的示例
一樣,如果希望忽略事件,只要呼叫父類的響應函式即可 。記得我們曾經說過,qt中的事件大部分是protected的,因此,重寫的函式必定存在著其父類中的響應函式,這個方法
是可行的 。為什麼要這麼做呢?因為我們無法確認父類中的這個處理函式沒有操作
,如果我們在子類中直接忽略事件,qt不會再去尋找其他的接受者,那麼父類的操作也就不能進行,這可能會有潛在的危險 。另外我們檢視
一下qwidget
的mousepressevent()函式的實現
:
void qwidget請注意第一條語句::mousepressevent(qmouseevent *event)
if (!rect().contains(event->pos()))
} }
,如果所有子類都沒有覆蓋mousepressevent函式,這個事件會在這裡被忽略掉,這暗示著這個元件
不關心這個事件,這個事件就可能被傳遞給其父元件 。
不過,事情也不是絕對的 。在乙個情形下,我們必須使用accept()和ignore()函式,那就是在視窗
關閉的時候 。如果你在視窗關閉時需要有個詢問對話方塊,那麼就需要這麼去寫:
void mainwindow::closeevent(qcloseevent * event)這樣,我們經過詢問之後才能正常退出程式else
} bool mainwindow::continuetoclose()
else
}
今天要說的是event()函式 。記得之前曾經提到過這個函式,說在事件物件建立完畢後,qt將這個事件物件傳遞給qobject的event()函式 。event()函式並不直接處理事件,而是將這些事件物件按照它們不同的型別
,分發給不同的事件處理器
(event handl
er) 。
event()函式主要用於事件的分發,所以,如果你希望在事件分發之前做一些操作,那麼,就需要注意這個event()函式了 。為了達到這種目的,我們可以重寫event()函式 。例如,如果你希望在視窗中的tab鍵按下時將焦點
移動到下一元件,而不是讓具有焦點的元件處理,那麼你就可以繼承
qwidget,並重寫它的event()函式,已達到這個目的:
bool mywidget::event(qevent *event)event()函式接受乙個qevent物件,也就是需要這個函式進行**的物件 。為了進行**,必定需要有一系列的型別判斷} return qwidget::event(event);
}
,這就可以呼叫qevent的type()函式,其返回值是qevent::type型別的列舉
。我們處理過自己需要的事件後,可以直接return回去,對於其他我們不關心的事件,需要呼叫父類的event()函式繼續**,否則這個元件就只能處理我們定義
的事件了 。
event()函式的返回值和事件的accept()和ignore()函式不同 。accept()和ignore()函式用於不同的事件處理器
bool qwidget::event(qevent *event)qwidget的event()函式使用乙個巨大的switch來判斷qevent的type,並且分發給不同的事件處理函式 。在事件處理函式之後,使用這個事件的isaccepted()方法,獲知這個事件是不是被接受,如果沒有被接受則event()函式立即返回false,否則返回true 。return true;
}
另外乙個必須重寫event()函式的情形是有自定義
事件的時候 。如果你的程式中有自定義事件,則必須重寫event()函式以便將自定義事件進行分發,否則你的自定義事件永遠也不會被呼叫 。
建立事件過濾器和安裝
事件過濾器
qt建立了qevent事件物件之後,會呼叫qobject的event()函式做事件的分發 。有時候,你可能需要在呼叫event()函式之前做一些另外的操作,比如,對話方塊上某些元件可能並不需要響應回車按下的事件,此時,你就需要重新定義元件的event()函式 。如果元件很多,就需要重寫很多次event()函式,這顯然沒有效率
。為此,你可以使用乙個事件過濾器,來判斷是否需要呼叫event()函式 。
qojbect有乙個eventfilter
()函式,用於建立事件過濾器 。這個函式的簽名
如下:
virtual bool qobject::eventfilter ( qobject * watched, qevent * event )如果watched物件安裝了事件過濾器,這個函式會被呼叫並進行事件過濾,然後才輪到元件進行事件處理 。在重寫這個函式時,如果你需要過濾掉某個事件,例如停止對這個事件的響應,需要返回true 。
bool mainwindow::eventfilter(qobject *obj, qevent *event)上面的例子中為mainwindow建立了乙個事件過濾器 。為了過濾某個元件上的事件,首先需要判斷這個物件是哪個元件,然後判斷這個事件的型別 。例如,我不想讓textedit元件處理鍵盤else
} else
}
事件,於是就首先找到這個元件,如果這個事件是鍵盤事件,則直接返回true,也就是過濾掉了這個事件,其他事件還是要繼續處理,所以返回false 。對於其他元件,我們並不保證是不是還有過濾器,於是最保險的辦法是呼叫父類的函式 。
在建立了過濾器之後,下面要做的是安裝這個過濾器 。安裝過濾器需要呼叫installeventfilter()函式 。這個函式的簽名如下:
void qobject::installeventfilter ( qobject * filterobj )這個函式是qobject的乙個函式,因此可以安裝到任何qobject的子類,並不僅僅是ui元件 。這個函式接收乙個qobject物件,呼叫了這個函式安裝事件過濾器的元件會呼叫filterobj定義的eventfilter()函式 。例如,textfield.installeventfilter(obj),則如果有事件傳送到textfield元件是,會先呼叫obj->eventfilter()函式,然後才會呼叫textfield.event() 。
如果乙個元件安裝了多個過濾器,則最後乙個安裝的會最先呼叫,類似於堆疊的行為 。
注意,如果你在事件過濾器中delete
了某個接收元件,務必將返回值設為true 。否則,qt還是會將事件分發給這個接收元件,從而導致程式崩潰
。事件過濾器和被安裝的元件必須在同一執行緒
,否則,過濾器不起作用 。另外,如果在install之後,這兩個元件到了不同的執行緒,那麼,只有等到二者重新回到同一執行緒的時候過濾器才會有效 。
事件的呼叫最終都會呼叫qcore
小結:關於qt類 qevent事件處理過程事件過濾器 的內容介紹按了,希望本文對你有所幫助
nginx事件處理過程
1.首先設定斷點 ngx epoll process events at src event modules ngx epoll module.c 575 2.請求http ip 3.nginx接收的客戶端的請求,進行accept事件處理,呼叫堆疊如下圖。4.accept處理完畢後,進行http的請...
PyQt學習隨筆 Qt事件類QEvent詳解
qobjects 物件通過呼叫 qobject.event 函式接收事件,可以通過在子類中重寫該函式來定義自己的事件處理 並可以新增使用者自定義的事件型別,qwidget.event 就是這樣乙個典型例子。預設情況下,事件被分發給類似 qobject.timerevent 和 qwidget.mou...
Qt5開發 的QEvent事件類
事件種類 qtimerevent 定時器事件 qmouseevent 滑鼠事件 qwheelevent 滑動滑鼠滑輪事件 qtabletevent qkeyevent 鍵盤事件 qfocusevent 焦點事件 qpaintevent 繪畫事件 qmoveevent 移動事件 qresizeeven...