一、Qt中事件处理的顺序
1、事件传递的过程
(1)、事件被组件对象处理后可能传递到其父组件对象
2、QEvent中的关键成员函数
实验一
#include "Widget.h"
#include <QEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
}
Widget::~Widget()
{
}
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";//1.会先打印Widget::event再打印Widget::keyPressEvent
//即先被事件总的事件函数处理,再在里面调用相应的事件处理函数
QWidget::keyPressEvent(e);
}
实验一
实验二:
MyEdit.h
#ifndef MYEDIT_H
#define MYEDIT_H
#include <QLineEdit>
class MyEdit : public QLineEdit
{
Q_OBJECT
public:
bool event(QEvent* e);
void keyPressEvent(QKeyEvent* e);
explicit MyEdit(QWidget *parent = 0);
signals:
public slots:
};
#endif // MYEDIT_H
MyEdit.h
MyEdit.cpp
#include "MyEdit.h"
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
MyEdit::MyEdit(QWidget *parent) :
QLineEdit(parent)
{
}
bool MyEdit::event(QEvent* e)
{
if(e->type()==QEvent::KeyPress)
{
qDebug() << "MyEdit::event";
}
return QLineEdit::event(e);
}
void MyEdit::keyPressEvent(QKeyEvent* e)
{
qDebug() << "MyEdit::keyPressEvent";
QLineEdit::keyPressEvent(e);
//e->ignore();没有这句时只打印MyEdit::event和MyEdit::keyPressEvent,有这句时
//打印 MyEdit::event和MyEdit::keyPressEvent、Widget::event和 Widget::keyPressEvent 说明可能传给父对象处理
}
MyEdit.cpp
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
#include "MyEdit.h"
class Widget : public QWidget
{
Q_OBJECT
MyEdit myEdit;
public:
bool event(QEvent* e);
void keyPressEvent(QKeyEvent* e);
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H
Widget.h
Widget.cpp
#include "Widget.h"
#include <QEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent), myEdit(this)
{
}
Widget::~Widget()
{
}
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.cpp
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();
}
main.cpp
二、Qt事件的过滤器
1、Qt中的事件过滤器
(1)、事件过滤器可以对其它组件接收到的事件进行监控
(2)、任意的QObject对象都可以作为事件过滤器使用
(3)、事件过滤器对象需要重写evenFilter()函数
2、组件通过installEventFilter()函数安装事件过滤器
(1)、事件过滤器在组件之前接收到事件
(2)、事件过滤器能够决定是否将事件转发到组件对象
3、事件过滤器的典型实现
重写事件过滤器函数
//1.判断是不是感兴趣的对象和事件
//2.若是,就决定是没收还是还是继续转发给感兴趣的对象
//3.若不是,就按默认的方式处理事件
//4.最后一定安装过滤器
bool Widget::eventFilter(QObject* obj, QEvent* e)
{
bool ret = true;
if(obj == &myEdit && (e->type() == QEvent::KeyPress))
{
qDebug() << "Widget::eventFilter";
QKeyEvent* evt = dynamic_cast<QKeyEvent*>(e);
switch(evt->key())
{
case Qt::Key_0://若按下0-9,则事件被传到文本框处理,输出,若不是,什么也不显示
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
ret = false;//如果是0-9,ret仍然是true,此时就会传递到感兴趣的对象
break;
default:
break;
}
}
else
{
ret = QWidget::eventFilter(obj, e);//如果不是感兴趣的事件或者对象,就按照默认方式处理
}
return ret;//返回true说明事件已被处理,返回false说明事件还未处理
}
重写事件过滤器函数
安装过滤器:
其它代码和上个例子一样
三、小结
(1)、Qt应用程序有严格的事件处理顺序
(2)、Qt事件在处理后可能传递给父组件对象
(3)、组件通过installEventFilter()函数安装事件过滤器
(4)、事件过滤器可以对其它组件接收到的事件进行监控
(5)、事件过滤器能够决定是否将事件转发到组件对象