本文已参与「新人创作礼」活动,一起开启掘金创作之路。
重写qt事件、事件处理步骤:
1、对目标对象调用installEventFilter()来注册监视对象(事件过滤器);
2、重写监视对象的eventFilter()函数处理目标对象的事件。
代码:
dialog.h:
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
bool eventFilter(QObject *, QEvent *);//对目标对象调用installEventFilter()来注册监视对象(事件过滤器);
private:
Ui::Dialog *ui;
};
dialog.cpp:
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->label->installEventFilter(this); //ui中创建了一个label
}
Dialog::~Dialog()
{
delete ui;
}
bool Dialog::eventFilter(QObject *obj, QEvent *e)
{
if(obj == ui->label) //判断是不是我创建的label触发了事件
{
if(e->type() == QEvent::MouseButtonPress) //如果label触发了鼠标点击的事件
{
qDebug()<<"press"<<endl;
return true; //表示停止处理该事件,此时目标对象和后面安装的事件过滤器就无法获得该事件
}
else
{
qDebug()<<"nopress"<<endl;
return false; //返回false,则表示事件需要作进一步处理
}
}
return Dialog::eventFilter(obj,e); //返回默认的事件过滤器
}
返回值:
上面有三种情况的返回值分别是
retrun true;
return false;
return Dialog::eventFilter(obj,e);
这三种情况分别表示
1)返回为真时,此时停止处理该事件,其他的事件过滤器无法接收到事件
2)返回为假,则将事件交给该物体的时间分发器处理
3)返回为Dialog::eventFilter(obj,e);表示将事件交给父类的事件分发器处理
点击了一次label后的结果:
编辑
图中出现一次press一次nopress的原因是代码中判断的是鼠标按下时会打印,而鼠标释放也是一个事件触发,这个时候不满足 e->type() == QEvent::MouseButtonPress这个条件。
原理:
在Qt中,当一个事件发生时(例如鼠标点击或某个键盘上的按键按下),其传递顺序如图所示。事件过滤器首先获得事件,其次才是部件的 event 函数,最后是部件的事件处理函数
编辑
当一个事件发生时,首先是事件过滤器(即eventFilter)先接收到,当我们没有对事件过滤器做重载操作时,事件过滤器就会将 事件发送给部件的event函数进而调用不见的事件处理函数。若是重载了,则先调用事件过滤器中的函数。