Qt中事件的传递
每个程序main()的最后调用QApplication类的exec(),它会使应用程序进入事件循环,这样就可以使应用程序在运行时接收发生的各种事件。一旦有事件发生,Qt便会构建一个相应的QEvent子类的对象来表示它。
以下是事件传递的例子:
//mylineedit.h #ifndef MYLINEEDIT_H #define MYLINEEDIT_H #include<QLineEdit> class MyLineEdit:public QLineEdit//手动添加LineEdit { Q_OBJECT public: MyLineEdit(QWidget *parent = 0); protected: void keyPressEvent(QKeyEvent *e); }; #endif // MYLINEEDIT_H
//mylineedit.cpp #include "mylineedit.h" #include<QKeyEvent> #include<QDebug> MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent) { } void MyLineEdit::keyPressEvent(QKeyEvent *e) { qDebug()<<tr("MyLineEdit键盘按下事件"); }
//widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class MyLineEdit;//前置声明 class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; MyLineEdit *lineEdit; protected: void keyPressEvent(QKeyEvent *e); }; #endif // WIDGET_H
//widget.cpp #include "widget.h" #include "ui_widget.h" #include"mylineedit.h" #include<QKeyEvent> #include<QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); lineEdit = new MyLineEdit(this); lineEdit->move(100,100); } Widget::~Widget() { delete ui; } void Widget::keyPressEvent(QKeyEvent *e) { qDebug()<<tr("Widget键盘按下事件"); }
//main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
结果为:


说明这时只执行了MyLineEdit类中的keyPressEvent()函数。
接下来继续对程序进行如下改动:
//mylineedit.h #include "mylineedit.h" #include<QKeyEvent> #include<QDebug> MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent) { } void MyLineEdit::keyPressEvent(QKeyEvent *e) { qDebug()<<tr("MyLineEdit键盘按下事件"); QLineEdit::keyPressEvent(e);//执行QLineEdit类的默认事件处理 e->ignore();//忽略该事件 }
结果为:

说明事件先传递给获得焦点的窗口部件,但如果该部件忽略掉该事件,这个事件就会传递给这个部件的父部件。
继续对程序进行如下改动:
//widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class MyLineEdit; class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); bool eventFilter(QObject *obj, QEvent *event);//事件过滤 private: Ui::Widget *ui; MyLineEdit *lineEdit; protected: void keyPressEvent(QKeyEvent *e); }; #endif // WIDGET_H
//widget.h #include "widget.h" #include "ui_widget.h" #include"mylineedit.h" #include<QKeyEvent> #include<QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); lineEdit = new MyLineEdit(this); lineEdit->move(100,100); lineEdit->installEventFilter(this);//在Widget上为lineEdit安装事件过滤器 } Widget::~Widget() { delete ui; } bool Widget::eventFilter(QObject *obj, QEvent *event) { if(obj == lineEdit){//先判断事件对象是不是lineEdit if(event->type() == QEvent::KeyPress)//判断事件类型 qDebug()<<tr("Widget的事件过滤器"); } return QWidget::eventFilter(obj, event); } void Widget::keyPressEvent(QKeyEvent *e) { qDebug()<<tr("Widget键盘按下事件"); }
结果为:

说明事件的传递顺序是:事件过滤器 --> 焦点部件的event()函数 --> 焦点部件的事件处理函数 --> 父部件的事件处理函数。

浙公网安备 33010602011771号