Qt中的事件处理
文章目錄
- 1 Qt中的事件處理
- 1.1 Qt中的事件處理過程
- 1.2 Qt中事件的傳遞過程
- 1.3 Qt中的事件過濾器
1 Qt中的事件處理
1.1 Qt中的事件處理過程
GUI程序原理回顧,圖形界面應用程序的消息處理模型如下:
思考:操作系統發送的消息如何轉變成Qt信號?
Qt平臺將系統產生的消息轉換成Qt事件:
- Qt事件是一個QEvent的對象。
- Qt事件用于描述程序內部或外部發生的動作。
- 任意的QObject對象都具備事件處理的能力。
GUI應用程序的事件處理方式:
場景分析:按鈕點擊
(圖中的序號4應該在序號5之后。)
QPushButton事件處理分析:
事件(QEvent)和信號(SIGNAL)的不同:
- 事件由具體對象進行處理,而信號是由對象在進行事件處理的過程中主動產生的。
- 改寫事件處理函數可能導致程序行為發生改變,但是信號是否存在對應的槽函數不會改變程序行為。
- 一般而言,信號在具體的事件處理函數中產生。
編程實驗:自定義事件處理函數(改寫按鈕的點擊事件)
QMyPushButton.h:
QMyPushButton.cpp:
#include "QMyPushButton.h" #include <QMouseEvent>QMyPushButton::QMyPushButton(QWidget* parent, QButtonListener* listener) : QPushButton(parent) {m_listener = listener; }void QMyPushButton::mouseReleaseEvent(QMouseEvent *e) {if( m_listener != NULL ){m_listener(this, e);e->accept();setDown(false);}else{QPushButton::mouseReleaseEvent(e);} }Widget.h:
#ifndef _WIDGET_H_ #define _WIDGET_H_#include <QtGui/QWidget> #include "QMyPushButton.h"class Widget : public QWidget {Q_OBJECTQMyPushButton myButton; protected slots:void onMyButtonClicked(); public:Widget(QWidget *parent = 0);~Widget(); };#endif // _WIDGET_H_Widget.cpp:
#include "Widget.h" #include <QDebug>void onMyButtonMouseRelease(QObject* sender, QMouseEvent* e) {qDebug() << "onMyButtonMouseRelease(QObject* sender, QMouseEvent* e)"; }Widget::Widget(QWidget *parent) : QWidget(parent), myButton(this, onMyButtonMouseRelease) {myButton.setText("QMyPushButton");connect(&myButton, SIGNAL(clicked()), this, SLOT(onMyButtonClicked())); }void Widget::onMyButtonClicked() {qDebug() << "onMyButtonClicked()"; }Widget::~Widget() {}main.cpp:
#include <QtGui/QApplication> #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }1.2 Qt中事件的傳遞過程
首先我們需要了解一點:事件被組件對象處理后可能傳遞到其父組件對象,也可能不傳遞到父組件對象。
QEvent中的關鍵成員函數:
- void ignore():接收者忽略當前事件,事件可能會傳遞給父組件。
- void accept():接收者期望處理當前事件。
- bool isAccepted():判斷當前事件是否被處理。
編程實驗:事件處理的順序
MyLineEdit.h:
MyLineEdit.cpp:
#include "MyLineEdit.h" #include <QDebug> #include <QEvent> #include <QKeyEvent>MyLineEdit::MyLineEdit(QWidget *parent) :QLineEdit(parent) { }bool MyLineEdit::event(QEvent* e) {if( e->type() == QEvent::KeyPress ){qDebug() << "MyLineEdit::event";}return QLineEdit::event(e); }void MyLineEdit::keyPressEvent(QKeyEvent* e) {qDebug() << "MyLineEdit::keyPressEvent";QLineEdit::keyPressEvent(e);// e->ignore(); // 如果調用了ignore函數,事件則會被傳遞到其父組件 }Widget.h:
#ifndef WIDGET_H #define WIDGET_H#include <QtGui/QWidget> #include "MyLineEdit.h"class Widget : public QWidget {Q_OBJECTMyLineEdit myLineEdit; public:Widget(QWidget* parent = 0);bool event(QEvent* e);void keyPressEvent(QKeyEvent* e);~Widget(); };#endif // WIDGET_HWidget.cpp:
#include "Widget.h" #include <QDebug> #include <QEvent>Widget::Widget(QWidget *parent): QWidget(parent), myLineEdit(this) {}bool Widget::event(QEvent* e) {if( e->type() == QEvent::KeyPress ){qDebug() << "Widget::event";}return QWidget::event(e); }void Widget::keyPressEvent(QKeyEvent* e) {qDebug() << "Widget::keyPressEvent";QWidget::keyPressEvent(e); }Widget::~Widget() {}main.cpp:
#include <QtGui/QApplication> #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }1.3 Qt中的事件過濾器
對于Qt中的事件過濾器:
- 事件過濾器可以對其他組件接收到的事件進行監控。
- 任意的QObject對象都可以作為事件過濾器使用。
- 事件過濾器對象需要重寫eventFilter()函數。
組件通過installEventFilter()函數安裝事件過濾器:
- 事件過濾器在組件之前接收到事件。
- 事件過濾器能夠決定是否將事件轉發到組件對象。
事件過濾器的典型實現:
編程實驗:事件過濾器的使用
大部分代碼和上面的代碼都相同,這里只貼出安裝事件過濾器、和事件過濾器的實現:
參考資料:
總結
- 上一篇: Qt中的QMap和QHash
- 下一篇: 汽车交强险收费标准