[Q学习]11 Qt事件系统——过滤事件

>原创文章,可以转载,转载时请以超链接形式保留本文地址、作者信息和本声明。否则将追究法律责任。

我们可能会遇到这样一种需求——监测某个对象的事件投递过程,分析或者拦截某个事件,这时我们就要用到事件过滤器了。什么是事件过滤器呢?事件过滤器本质上是QObject子类的一个对象,该对象重载了eventFilter接口。

如果使用事件过滤器呢?

1 定义QObject子类A,重载eventFilter接口,在这个接口中实现过滤功能;

2 被观察者必须是QObject或者QObject子类的对象,调用QObject::installEventFilter()传入A的对象,即可完成A对该对象的监测;

3 过滤器比事件实际接受者要早一步得到事件。

假设有一个类CInspectA 用于截获事件,当截获事件时输出字符串提示,代码调用过程如下:

监测者类声明:

#ifndef CINSPECT_H
#define CINSPECT_H

#include <QObject>

class CInspectA : public QObject
{
    Q_OBJECT
public:
    explicit CInspectA(QObject *parent = 0);
signals:

public slots:

protected:
    virtual bool eventFilter(QObject *obj, QEvent *event);
};

#endif // CINSPECT_H
实现
#include "cinspect.h"
#include <QDebug>

CInspectA::CInspectA(QObject *parent) : QObject(parent)
{

}

bool CInspectA::eventFilter(QObject *obj, QEvent *event)
{
	qDebug() << "inspect :" << obj->objectName() << ", event id = " << event->type();

    return true;
}

客户端调用

#include <QCoreApplication>
#include <QWidget>
#include "cinspect.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 投递事件
    CInspectA I;
    QObject A;
    A.setObjectName("A");

    // 监测A事件
    A.installEventFilter(&I);
    QEvent E(QEvent::MouseButtonPress);
 	A.event(&E);

    return a.exec();
}

预期结果是输出inspect : "A" , event id =  XXXXXX,但是运行之后,发现没有任何输出。为什么呢?原因在于“A.event(&E);”这个调用说明A已经开始处理事件了,这时事件过滤器不会起作用。这里涉及到一个概念:发送(send)和投递(delivery)。发送事件是有对象A发送到对象B,这是一个用户调用的过程;投递是Qt框架沿着接收者的继承关系找到最终处理接口的过程。

为了使过滤器生效,我要们“发送”事件,而不是“投递”事件,修改一下main函数:

#include <QCoreApplication>
#include <QWidget>
#include "cinspect.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 投递事件
    CInspectA I;
    QObject A;
    A.setObjectName("A");

    // 监测A事件
    A.installEventFilter(&I);
    QEvent E(QEvent::MouseButtonPress);
    QCoreApplication::postEvent(&A, &E);
    
    return a.exec();
}

此处改用QCoreApplication::postEvent发送事件,运行之后输出:inspect : "A" , event id =  QEvent::Type(MouseButtonPress)。

下一篇,我们将讲述事件发送的过程。








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值