歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> QT的Event Filter

QT的Event Filter

日期:2017/2/28 16:20:50   编辑:Linux教程

一直對Event Filter似懂非懂, 通過看C++ GUI Programming with Qt4, Second Edition, 爭取搞明白. 順便自己把英文翻譯成中文, 算是自己做的筆記了.

Installing Event Filters
QT事件模塊一個真正強大的特性是可以設置一個QObject的實例去監測另外一個QObject實例的事件,在被監測的實例see之前.

假設我們有一個CustomerInfoDialog這樣的widget, 它由幾個QLineEdit組成.我們想用Spacer鍵來轉變focus到下一個QLineEdit.這個非標准的行為可能對一個內部的程序很合適, 需要培訓它的用戶來使用它. 一個直接的方法是子類QLineEdit,然後重新實現keyPressEvent()來調用focusNextChild(), 像這樣:
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Space)
{
focusNextChild();
}
else
{
QLineEdit::keyPressEvent(event);
}
}

這個方法有一個主要的弊端: 如果我們在這個form中用到幾個不同類型的widget(比如QComboBox和QSpinBox), 我們必須也子類化它們來表現出相同的行為. 一個更好的方案是讓CustomerInfoDialog來監控它的子widget的按鍵事件,

在監測的代碼裡執行需要的行為. 這可以用event Filter來達到. 設置一個event filter有兩個步驟:
1. 在目標對象上調用installEventFilter(),將監測對象注冊到目標對象上.
2. 在監測對象的eventFilter()方法裡處理目標對象的事件.

在ctor裡注冊監測對象是一個好地方:
CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) :QDialog(parent)
{
...
firstNameEdit->installEventFilter(this);
lastNameEdit->installEventFilter(this);
cityEdit->installEventFilter(this);
phoneNumberEdit->installEventFilter(this);
}

一旦event Filter注冊了, 發送到firstNameEdit, lastNameEdit, cityEdit和phoneNumberEdit的事件在被發送到原來的目的地之前, 會先發到CustomerInfoDialog的eventFilter()函數.

這是接收這些事件的eventFilter()函數:
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);
}

首先,我們檢查是否目標widget是一個QLineEdit. 如果是個key Press事件, 把它轉換為QKeyEvent, 並檢查哪個鍵值被按下.

如果是space, 我們調用focusNextChild()把focus傳到focus鏈上的下一個widget上, 返回true告訴Qt我們已經處理了這個事件. 如果我們返回false, Qt會發送這個event到它原來的目的地,導致一個假的空格被插入到QLineEdit.

如果目標widget不是QLineEdit, 或者這個event不是一個space按鍵, 我們把控制權傳回到基類的eventFilter去. 目標wdiget可以是基類-QDialog正在監測的某個widget.

Copyright © Linux教程網 All Rights Reserved