QT事件过滤器eventFilter函数
Qt的事件模型一個強大的功能是一個QObject對象能夠監視發送其他QObject對象的事件,在事件到達之前對其進行處理。
假設我們有一個CustomerInfoDialog控件,由一些QLineEdit控件組成。我們希望使用Space鍵得到下一個QLineEdit的輸入焦點。一個最直接的方法是繼承QLineEdit重寫keyPressEvent()函數,當點擊了Space鍵時,調用focusNextChild():
void MyLineEdit::keyPressEvent(QKeyEvent *event) {if (event->key() == Qt::Key_Space) {focusNextChild();} else {QLineEdit::keyPressEvent(event);} }這個方法有一個最大的缺點:如果我們在窗體中使用了很多不同類型的控件(QComboBox,QSpinBox等等),我們也要繼承這些控件,重寫它們的keyPressEvent()。一個更好的解決方法是讓CustomerInfoDialog監視其子控件的鍵盤事件,在監視代碼處實現以上功能。這就是事件過濾的方法。實現一個事件過濾包括兩個步驟:
注冊監視對象的位置是在CustomerInfoDialog的構造函數中:
CustomerInfoDialog::CustomerInfoDialog(QWidget *parent): QDialog(parent) {…firstNameEdit->installEventFilter(this);lastNameEdit->installEventFilter(this);cityEdit->installEventFilter(this);phoneNumberEdit->installEventFilter(this); }事件過濾器注冊后,發送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit控件的事件首先到達CustomerInfoDialog::eventFilter()函數,然后在到達最終的目的地。
下面是eventFilter()函數的代碼:
首先,我們看是目標控件是否為QLineEdit,如果事件為鍵盤事件,把QEvent轉換為QKeyEvent,確定被敲擊的鍵。如果為Space鍵,調用focusNextChild(),把焦點交給下一個控件,返回true通知Qt已經處理了這個事件,如果返回false,Qt將會把事件傳遞給目標控件,把一個空格字符插入到QLineEdit中。
如果目標控件不是QLineEdit,或者事件不是Space敲擊事件,把控制權交給基類QDialog的eventFilter()。目標控件也可以是基類QDialog正在監視的控件。(在Qt4.1中,QDialog沒有監視的控件,但是Qt的其他控件類,如QScrollArea,監視一些它們的子控件)
Qt的事件處理有5中級別:
許多事件類型,包括鼠標,鍵盤事件,是能夠傳播的。如果事件在到達目標對象的途中或者由目標對象處理掉,事件處理的過程會重新開始,不同的是這時的目標對象是原目標對象的父控件。這樣從父控件再到父控件,知道有控件處理這個事件或者到達了最頂級的那個控件。
圖7.2顯示了一個鍵盤事件在一個對話框中從子控件到父控件的傳播過程。當用戶敲擊一個鍵盤,時間首先發送到有焦點的控件上(這個例子中是QCheckBox)。如果QCheckBox沒有處理這個事件,Qt把事件發送到QGroupBox中,如果仍然沒有處理,則最后發送到QDialog中。
總結
以上是生活随笔為你收集整理的QT事件过滤器eventFilter函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV与图像处理学习二——图像直方
- 下一篇: 吴恩达《机器学习》学习笔记一——初识机器