W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Qt 創(chuàng)建了 QEvent 事件對象之后,會調(diào)用 QObject 的 event()函數(shù)做事件的分發(fā)。有時候,你可能需要在調(diào)用 event()函數(shù)之前做一些另外的操作,比如,對話框上某些組件可能并不需要響應(yīng)回車按下的事件,此時,你就需要重新定義組件的 event()函數(shù)。如果組件很多,就需要重寫很多次 event()函數(shù),這顯然沒有效率。為此,你可以使用一個事件過濾器,來判斷是否需要調(diào)用 event()函數(shù)。
QOjbect 有一個 eventFilter()函數(shù),用于建立事件過濾器。這個函數(shù)的簽名如下:
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event )
如果 watched 對象安裝了事件過濾器,這個函數(shù)會被調(diào)用并進行事件過濾,然后才輪到組件進行事件處理。在重寫這個函數(shù)時,如果你需要過濾掉某個事件,例如停止對這個事件的響應(yīng),需要返回 true。
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == textEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
上面的例子中為 MainWindow 建立了一個事件過濾器。為了過濾某個組件上的事件,首先需要判斷這個對象是哪個組件,然后判斷這個事件的類型。例如,我不想讓 textEdit 組件處理鍵盤事件,于是就首先找到這個組件,如果這個事件是鍵盤事件,則直接返回 true,也就是過濾掉了這個事件,其他事件還是要繼續(xù)處理,所以返回 false。對于其他組件,我們并不保證是不是還有過濾器,于是最保險的辦法是調(diào)用父類的函數(shù)。
在創(chuàng)建了過濾器之后,下面要做的是安裝這個過濾器。安裝過濾器需要調(diào)用 installEventFilter()函數(shù)。這個函數(shù)的簽名如下:
void QObject::installEventFilter ( QObject * filterObj )
這個函數(shù)是 QObject 的一個函數(shù),因此可以安裝到任何 QObject 的子類,并不僅僅是 UI 組件。這個函數(shù)接收一個 QObject 對象,調(diào)用了這個函數(shù)安裝事件過濾器的組件會調(diào)用 filterObj 定義的eventFilter()函數(shù)。例如,textField.installEventFilter(obj),則如果有事件發(fā)送到textField 組件是,會先調(diào)用 obj->eventFilter()函數(shù),然后才會調(diào)用 textField.event()。
當(dāng)然,你也可以把事件過濾器安裝到 QApplication 上面,這樣就可以過濾所有的事件,已獲得更大的控制權(quán)。不過,這樣做的后果就是會降低事件分發(fā)的效率。
如果一個組件安裝了多個過濾器,則最后一個安裝的會最先調(diào)用,類似于堆棧的行為。
注意,如果你在事件過濾器中 delete 了某個接收組件,務(wù)必將返回值設(shè)為 true。否則,Qt 還是會將事件分發(fā)給這個接收組件,從而導(dǎo)致程序崩潰。
事件過濾器和被安裝的組件必須在同一線程,否則,過濾器不起作用。另外,如果在 install 之后,這兩個組件到了不同的線程,那么,只有等到二者重新回到同一線程的時候過濾器才會有效。
事件的調(diào)用最終都會調(diào)用 QCoreApplication 的 notify()函數(shù),因此,最大的控制權(quán)實際上是重寫QCoreApplication 的 notify()函數(shù)。由此可以看出,Qt 的事件處理實際上是分層五個層次:重定義事件處理函數(shù),重定義 event()函數(shù),為單個組件安裝事件過濾器,為 QApplication 安裝事件過濾器,重定義 QCoreApplication 的 notify()函數(shù)。這幾個層次的控制權(quán)是逐層增大的。
本文出自 “豆子空間” 博客,請務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/194031
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: