- Event Filter
舉例來說,對QWidget按鍵事件的Tab鍵處理而言,如果圖形介面中有很多的元件,每個圖型元件都要如當中的範例重新定義event()方法,顯然是非常沒有效率且沒什麼維護性的方法。
可以藉由自定義一個物件繼承QObject(或其子類別),重新定義它的eventFilter()方法,例如自定義了一個FilterObject,希望Tab鍵可以用來將焦點轉移至下一個子元件:
bool FilterObject::eventFilter(QObject *object, QEvent *event) { if(event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Tab) { // 處理Tab鍵 return true; } } return false; }eventFilter()的object參數表示事件發生的來源物件,eventFilter()若傳回false,則安裝該事件過濾器的物件之event()就會繼續執行,若傳回true,則安裝該事件過濾器的物件之event()方法就不會被執行,由此進行事件的攔截處理。
要為指定的物件安裝事件過濾器,可以使用物件的installEventFilter()方法,例如:
QLineEdit *nameEdit = new QLineEdit; QLineEdit *addressEdit = new QLineEdit; ... FilterObject filter = new FilterObject; ... nameEdit->installEventFilter(filter); addressEdit->installEventFilter(filter); ....
Notes:
- 也可以將事件過濾器安裝在QApplication,在任何的事件發生後呼叫每個物件的event()方法之前,會先經過事件過濾器,這可提供更多控制應用程式事件的能力。
- Qt的事件迴圈與sendEvent()方法會呼叫QCoreApplication(QApplication的父類別)的notify()以分派事件,如果想要完全控制Qt應用程式的事件,則可以重新定義notify()方法。
由此可以看出Qt事件處理的五個層次:
- 重新定義事件處理者
- 重新定義event()方法
- 為個別物件安裝事件過濾器
- 為QApplication安裝事件過濾器
- 重新定義QCoreApplication的notify()方法
0 意見:
張貼留言