QT類 Qevent事件處理過程 事件過濾器

2021-06-02 08:50:44 字數 4588 閱讀 5059

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)   

}  return qwidget::event(event);  

}

event()函式接受乙個qevent物件,也就是需要這個函式進行**的物件  。為了進行**,必定需要有一系列的型別判斷

,這就可以呼叫qevent的type()函式,其返回值是qevent::type型別的列舉

。我們處理過自己需要的事件後,可以直接return回去,對於其他我們不關心的事件,需要呼叫父類的event()函式繼續**,否則這個元件就只能處理我們定義

的事件了  。

event()函式的返回值和事件的accept()和ignore()函式不同  。accept()和ignore()函式用於不同的事件處理器

bool qwidget::event(qevent *event)   

return true;  

}

qwidget的event()函式使用乙個巨大的switch來判斷qevent的type,並且分發給不同的事件處理函式  。在事件處理函式之後,使用這個事件的isaccepted()方法,獲知這個事件是不是被接受,如果沒有被接受則event()函式立即返回false,否則返回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)  

else   

} else   

}

上面的例子中為mainwindow建立了乙個事件過濾器  。為了過濾某個元件上的事件,首先需要判斷這個物件是哪個元件,然後判斷這個事件的型別  。例如,我不想讓textedit元件處理鍵盤

事件,於是就首先找到這個元件,如果這個事件是鍵盤事件,則直接返回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...