首先要明白一個概念,事件和信號並不一樣,比如單擊一下鼠標,就會產生鼠標事件(QMouseEvent),是對這個動作的描述,而因為按鈕被按下了,按鈕會發出clicked()的單擊信號(是按鈕控件產生的)。
1.事件處理方式:
method 1:重新實現部件的事件處理函數,如:mousePressEvent(),keyPressEvent()等等。是最常用的方法!!!
method 2:重新實現notify()函數。需要繼承QApplication類,可以再事件過濾事件之前獲得事件,一次只可以處理一個事件。
method 3:向QApplication的全局對象安裝時間過濾器,一個程序只有一個QApplication對象,可以處理多個事件,與method 2功能相同。
method 4:重新實現event()函數。QObject的event()函數可以再默認事件處理函數之前獲得該事件。
method 5:在對象上安裝事件過濾器。
2.事件傳遞過程:
父部件的事件過濾器 -> 本部件的event()函數 -> 本部件的事件處理函數 -> 父部件的處理函數(前提是子部件忽略該事件)
父部件的代碼示例(分別為.h和.cpp):
public: bool eventFilter(QObject *obj, QEvent *event); protected: void keyPressEvent(QKeyEvent *event); bool Widget::eventFilter(QObject *obj, QEvent *event) { if(obj == lineEidt) { if(event->type() == QEvent::KeyPress) qDebug() << "widget的事件過濾器"; } return QWidget::eventFilter(obj,event); } void Widget::keyPressEvent(QKeyEvent *event) { qDebug() << "widget鍵盤按下事件"; }
子部件的代碼實例:(QLineEdit控件)
public: bool event(QEvent *event); protected: void keyPressEvent(QKeyEvent *event); bool MyLineEdit::event(QEvent *event) { if(event->type() == QEvent::KeyPress) { qDebug() << "MyLineEdit的event()函數"; event->ignore(); return true; } return QLineEdit::event(event); } void MyLineEdit::keyPressEvent(QKeyEvent *event) { qDebug() << "MyLineEdit鍵盤按下事件"; QLineEdit::keyPressEvent(event); event->ignore(); }
運行結果如下:(如果在子部件沒有忽略事件,那么父部件的事件處理函數不會被調用)
3.事件過濾器:
只是QObject 的兩個函數:
installEventFilter();安裝事件過濾器
eventFilter(QObject *obj, QEvent *event);實現事件處理
4.事件發送:
QApplication類的sendEvent()和postEvent();
區別:
postEvent | sendEvent |
放到等待調度隊列 | 立即處理 |
必須在堆上(new)創建QEvent對象,會自動刪除 | 無法自動刪除,需要在棧上創建QEvent對象(系統釋放) |
5.事件處理函數:
函數非常多,但這里只總結經常使用到的。
QMouseEvent,QWheelEvent
void mouseDoubleClickEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void wheelEvent(QWheelEvent *event);
QKeyEvent,QTimerEvent
void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void timerEvent(QTimerEvent *event);