1、Qt中事件处理的顺序
1.1、 事件传递的过程
1.1.1、 事件被组件对象处理后可能(并不是一定)传递到其父组件对象
1.2、QEvent中的关键成员函数
实验一:
MyEdit.h
#ifndef _MYEDIT_H_
#define _MYEDIT_H_
#include <QLineEdit>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
class MyEdit : public QLineEdit
{
Q_OBJECT
public:
explicit MyEdit(QWidget *parent = 0);
bool event(QEvent* e); //这个QLineEdit也要实现消息处理函数。
void keyPressEvent(QKeyEvent* e);
signals:
public slots:
};
#endif // QLINEEDIT_H
MyEdit.cpp实现文件
#include "MyEdit.h"
MyEdit::MyEdit(QWidget *parent) :
QLineEdit(parent)
{
}
bool MyEdit::event(QEvent* e) //这个QLineEdit也要实现消息处理函数。
{
if(e->type() == QEvent::KeyPress)
{
qDebug() << "bool MyEdit::event(QEvent* e) ";
}
return QLineEdit::event(e);
}
void MyEdit::keyPressEvent(QKeyEvent* e)
{
qDebug() << "MyEdit::keyPressEvent(QKeyEvent* e)";
QLineEdit::keyPressEvent(e);
//e->ignore();//没有这句时只打印MyEdit::event和MyEdit::keyPressEvent,有这句时打印 MyEdit::event和MyEdit::keyPressEvent、Widget::event和 Widget::keyPressEvent 说明可能传给父对象处理
}
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.cpp实现文件
#include "Widget.h"
#include <QEvent>
#include <QKeyEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent), myEdit(this)
{
}
Widget::~Widget()
{
}
bool Widget::event(QEvent *e) //重写总的事件处理函数。
{
//qDebug() << e->type();
if(e->type() == QEvent::KeyPress)
{
qDebug() << "Widget::event";
}
return QWidget::event(e); //返回是否执行成功?
}
void Widget::keyPressEvent(QKeyEvent *e) //按键点击的具体事件。
{
qDebug() << "Widget::keyPressEvent(QKeyEvent *e)";//1、会先打印widget::event再打印Widget::keyPressEvent,即先被总的事件函数处理,然后调用相应具体的事件处理函数。
QWidget::keyPressEvent(e);
}
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();
}
2、Qt事件的过滤器
2.1、 Qt中的事件过滤器
2.1.1、 事件过滤器可以对其它组件接收到的事件进行监控
2.1.2、 任意的QObject对象都可以作为事件过滤器使用
2.1.3、 事件过滤器对象需要重写evenFilter()函数
2.2、 组件通过installEventFilter()函数安装事件过滤器
2.2.1、 事件过滤器在组件之前接收到事件
2.2.2、 事件过滤器能够决定是否将事件转发到组件对象
2.3、事件过滤器的典型实现
2.4、添加过滤器的实现代码。
//1、判断是不是感兴趣的对象和事件
//2、若是,就决定是没收还是继续转发给感兴趣的对象
//3、若不是,就按默认的方式处理事件
//4、最后一定安装时间过滤器。
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
bool ret = true;
if(obj == &myEdit && (e->type() == QEvent::KeyPress))
{
qDebug() << "Widget::eventFilter(QObject *obj, QEvent *e)";
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说明事件还未处理。
}
!!!必须有的安装过滤器代码。 其他代码和上个例子一样。
3、小结
3.1、 Qt应用程序有严格的事件处理顺序
3.2、 Qt事件在处理后可能传递给父组件对象
3.3、 组件通过installEventFilter()函数安装事件过滤器
3.4、 事件过滤器可以对其它组件接收到的事件进行监控
3.5、 事件过滤器能够决定是否将事件转发到组件对象