詳解 Qt 事件過濾器
Qt 事件過濾器是本文要介紹的內(nèi)容,Qt 事件模型一個真正強大的特色是一個QObject的實例能夠管理另一個QObject 實例的事件。
讓我們試著設(shè)想已經(jīng)有了一個CustomerInfoDialog的小部件。CustomerInfoDialog 包含一系列QLineEdit. 現(xiàn)在,我們想用空格鍵來代替Tab,使焦點在這些QLineEdit間切換。
一個解決的方法是子類化QLineEdit,重新實現(xiàn)keyPressEvent(),并在keyPressEvent()里調(diào)用focusNextChild()。像下面這樣:
- void MyLineEdit::keyPressEvent(QKeyEvent *event)
- {
- if (event->key() == Qt::Key_Space) {
- focusNextChild();
- } else {
- QLineEdit::keyPressEvent(event);
- }
- }
但這有一個缺點。如果CustomerInfoDialog里有很多不同的控件(比如QComboBox,QEdit,QSpinBox),我們就必須子類化這么多控件。這是一個煩瑣的任務(wù)。
一個更好的解決辦法是: 讓CustomerInfoDialog去管理他的子部件的按鍵事件,實現(xiàn)要求的行為。我們可以使用事件過濾器。
一個事件過濾器的安裝需要下面2個步驟:
1、調(diào)用installEventFilter()注冊需要管理的對象。
2、在eventFilter() 里處理需要管理的對象的事件。
一般,推薦在CustomerInfoDialog的構(gòu)造函數(shù)中注冊被管理的對象。像下面這樣:
- CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) : QDialog(parent){ ...
- firstNameEdit->installEventFilter(this);
- lastNameEdit->installEventFilter(this);
- cityEdit->installEventFilter(this);
- phoneNumberEdit->installEventFilter(this);
- }
一旦,事件管理器被注冊,發(fā)送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit的事件將首先發(fā)送到eventFilter()。
下面是一個 eventFilter()函數(shù)的實現(xiàn):
- bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)
- {
- if (target == firstNameEdit || target == lastNameEdit
- || target == cityEdit || target == phoneNumberEdit) {
- if (event->type() == QEvent::KeyPress) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Space) {
- focusNextChild();
- return true;
- }
- }
- }
- return QDialog::eventFilter(target, event);
- }
在上面的函數(shù)中,我們首先檢查目標部件是否是 firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit。接著,我們判斷事件是否是按鍵事件。如果事件是按鍵事件,我們把事件轉(zhuǎn)換為QKeyEvent。接著,我們判斷是否按下了空格鍵,如果是,我們調(diào)用focusNextChild(),把焦點傳遞給下一個控件。然后,返回,true通知Qt,我們已經(jīng)處理了該事件。
如果返回false的話,Qt繼續(xù)將該事件發(fā)送給目標控件,結(jié)果是一個空格被插入到QLineEdit中。
如果目標控件不是 QLineEdit,或者按鍵不是空格鍵,我們將把事件傳遞給基類的eventFilter()函數(shù)。
Qt提供5個級別的事件處理和過濾:
1、重新實現(xiàn)事件函數(shù)。 比如: mousePressEvent(), keyPress-Event(), paintEvent() 。
這是最常規(guī)的事件處理方法。
2、重新實現(xiàn)QObject::event().
這一般用在Qt沒有提供該事件的處理函數(shù)時。也就是,我們增加新的事件時。
3、安裝事件過濾器
4、在 QApplication 上安裝事件過濾器。
這之所以被單獨列出來是因為: QApplication 上的事件過濾器將捕獲應(yīng)用程序的所有事件,而且***個獲得該事件。也就是說事件在發(fā)送給其它任何一個event filter之前發(fā)送給QApplication的event filter。
5、重新實現(xiàn)QApplication 的 notify()方法.
Qt使用 notify()來分發(fā)事件。要想在任何事件處理器捕獲事件之前捕獲事件,***的方法就是重新實現(xiàn)QApplication 的 notify()方法。
小結(jié):關(guān)于Qt 事件過濾器的內(nèi)容介紹完了,希望本文對你有所幫助。如果需要更多內(nèi)容,請參考編輯推薦。