目录
前言
Qt事件处理(二)——事件处理链中事件的处理过程是先判断发生事件,控件本身是否对事件进行处理,然后传递给父对象。但是事件还有另外一种处理方法,安装事件过滤器。可以认为事件产生的时候先在父控件中对事件进行处理,然后选择是否传递给子对象进行处理。
事件过滤器
事件过滤器函数
installEventFilter()和eventFilter()
安装事件过滤器的位置
在
QObject中安装事件过滤器
在这张图片中,MainWindow中有些控件安装了事件过滤器,有些空间没有安装事件过滤器。对应安装了事件过滤器的,我们可以重写eventFilter()来在MainWindow()中处理事件。前提是我们指定控件installEventFilter()安装在MainWindow()中。
注意:我们可以对一个控件安装多个过滤器,以后有需求继续补充。在
QApplication中安装事件过滤器
如果给QApplication安装事件过滤器,相当于在所有的控件对事件进行处理之前,已经在QApplication中对事件进行了处理。
QApplication()中也可以安装多个事件过滤器。安装的事件过滤器,最后安装的先执行。
#include "dialog.h"
#include <QApplication>
class DemoFilter
{
public:
bool eventFilter(QObject *, QEvent *);
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
a.installEventFilter(new DemoFilter);
return a.exec();
}
- 子类化
QApplication并且重新实现notify()
我们也可以在子类化QApplication,也就是继承QApplication,然后重写notify()函数来对事件进行处理。
class MyApplication : public QApplication
{
bool notify(QObject*, QEvent*)
{
}
};
代码
建立三个QLineEdit,默认我们按回车键来对跳转到下一个QLineEdit,但是现在我们修改为按空格键来跳转到下一个QLineEdit。
给对应的QObject安装事件过滤器
- main.cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
- dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
bool eventFilter(QObject *, QEvent *);
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
- dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QKeyEvent>
// Dialog is Filter
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->nameLineEdit->installEventFilter(this);
ui->idLineEdit->installEventFilter(this);
ui->phoneNumberLineEdit->installEventFilter(this);
}
Dialog::~Dialog()
{
delete ui;
}
// target is the object which trigger event
bool Dialog::eventFilter(QObject *target, QEvent *event)
{
if(target == ui->nameLineEdit ||
target == ui->idLineEdit ||
target == ui->phoneNumberLineEdit)
{
// QEvent
if(event->type() == QEvent::KeyPress)
{
// QKeyEvent
QKeyEvent *keyEvent = (QKeyEvent*)event;
if(keyEvent->key() == Qt::Key_Space)
{
focusNextChild();
return true;
}
}
}
// QDialog's filter and Dialog's filter
// if the target has other event, use default event.
return QDialog::eventFilter(target, event);
}
- dialog.ui
这三个窗口的objectName分别是nameLineEdit,phoneNumberLineEdit,idLineEdit。
总结
事件处理的方法如下:
1. 重新实现事件处理器
2. 重新实现QObject::event()
3. 在QObject中安装事件过滤器
4. 在QApplication对象中安装事件过滤器(全局事件处理)
5. 子类化QApplication并且重新实现notify()(全局事件处理)
感觉来说,方法1~方法3都比较适合做事件处理。
340



被折叠的 条评论
为什么被折叠?



