QT事件過濾器

咱們試着設想已經有了一個CustomerInfoDialog的小部件。CustomerInfoDialog 包含一系列QLineEdit. 如今,咱們想用空格鍵來代替Tab,使焦點在這些QLineEdit間切換。 一個解決的方法是子類化QLineEdit,從新實現keyPressEvent(),並在keyPressEvent()裏調用focusNextChild()。像下面這樣: void MyLineEdit::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { focusNextChild(); } else { QLineEdit::keyPressEvent(event); } } 但這有一個缺點。若是CustomerInfoDialog裏有不少不一樣的控件(好比QComboBox,QEdit,QSpinBox),咱們就必須子類化這麼多控件。這是一個煩瑣的任務。 一個更好的解決辦法是: 讓CustomerInfoDialog去管理他的子部件的按鍵事件,實現要求的行爲。咱們可使用事件過濾器。 一個事件過濾器的安裝須要下面2個步驟: 1, 調用installEventFilter()註冊須要管理的對象。 2,在eventFilter() 裏處理須要管理的對象的事件。 通常,推薦在CustomerInfoDialog的構造函數中註冊被管理的對象。像下面這樣: CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) : QDialog(parent){ ... firstNameEdit->installEventFilter(this); lastNameEdit->installEventFilter(this); cityEdit->installEventFilter(this); phoneNumberEdit->installEventFilter(this); } 一旦,事件管理器被註冊,發送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit的事件將首先發送到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(event); if (keyEvent->key() == Qt::Key_Space) { focusNextChild(); return true; } } } return QDialog::eventFilter(target, event); } 在上面的函數中,咱們首先檢查目標部件是不是 firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit。接着,咱們判斷事件是不是按鍵事件。若是事件是按鍵事件,咱們把事件轉換爲QKeyEvent。接着,咱們判斷是否按下了空格鍵,若是是,咱們調用focusNextChild(),把焦點傳遞給下一個控件。而後,返回,true通知Qt,咱們已經處理了該事件。 若是返回false的話,Qt繼續將該事件發送給目標控件,結果是一個空格被插入到QLineEdit中。 若是目標控件不是 QLineEdit,或者按鍵不是空格鍵,咱們將把事件傳遞給基類的eventFilter()函數。 Qt提供5個級別的事件處理和過濾: 1,從新實現事件函數。 好比: mousePressEvent(), keyPress-Event(), paintEvent() 。 這是最常規的事件處理方法。 2,從新實現QObject::event(). 這通常用在Qt沒有提供該事件的處理函數時。也就是,咱們增長新的事件時。 3,安裝事件過濾器 4,在 QApplication 上安裝事件過濾器。 這之因此被單獨列出來是由於: QApplication 上的事件過濾器將捕獲應用程序的全部事件,並且第一個得到該事件。也就是說事件在發送給其它任何一個event filter以前發送給QApplication的event filter。 5,從新實現QApplication 的 notify()方法. Qt使用 notify()來分發事件。要想在任何事件處理器捕獲事件以前捕獲事件,惟一的方法就是從新實現QApplication 的 notify()方法。
相關文章
相關標籤/搜索