Qt--事件过滤器

20 篇文章 3 订阅

写在前面

Qt中的事件过滤器(Event Filter)是一种机制,用于拦截并处理特定类型的事件。但和Qt–事件分发器一文中提到的事件分发器有些区别。

事件过滤器的工作原理

这里同样使用一个简单的示例图帮助理解:
事件过滤器
这里假设有一个Widget父窗口,该窗口中有三个自定义的控件,而且这三个自定义控件中都有重写事件分发器事件。

当父窗口收到来自消息循环的某一事件(信号)时,若父窗口有安装事件过滤器,则会在事件过滤器函数中判断该事件要发往哪个控件(子控件),这就是事件过滤器的作用。

事件过滤器的使用

要使用事件过滤器,需进行以下两步:
①给需要事件过滤的子控件安装事件过滤器
②重写父窗口的事件过滤器函数

例这里在Widget父窗口中给label子控件安装事件过滤器,并在Widget父窗口中重写事件过滤器,以过滤发往label子控件的事件。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    //重写事件过滤器
    bool eventFilter(QObject* obj, QEvent* e);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"
#include <QEvent>
#include <QMouseEvent>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //安装事件过滤器
    ui->label->installEventFilter(this);


}

Widget::~Widget()
{
    delete ui;
}

//重写事件过滤器
bool Widget::eventFilter(QObject* obj, QEvent* e)
{
    //拦截发往label子控件的鼠标按下事件
    if (obj == ui->label)
    {
        if (e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent* mouseEv = static_cast<QMouseEvent*>(e);
            QString qs = QString("父窗口的事件过滤器中拦截鼠标按下, x = %1, y = %2").arg(mouseEv->x()).arg(mouseEv->y());
            qDebug() << qs;

            return true;
        }

    }

    return QWidget::eventFilter(obj, e);
}

运行可以看到鼠标按下事件会在Widget的事件过滤器中被拦截:
事件过滤器效果

事件过滤器和事件分发器的区别

Qt中的事件分发器(Event Dispatcher)和事件过滤器(Event Filter)都是用于处理事件的机制,但它们的作用和实现方式有所不同。

事件分发器(Event Dispatcher)是Qt中的一个重要组件,它负责将一个对象发出的事件分发给该对象的所有子对象,以及所有被该对象设置为接受该事件类型的父对象。事件分发器可以确保同一时间只有一个子对象或父对象接收到同一个事件,从而避免了事件冲突(event collision)的问题。事件分发器还提供了一些高级功能,如事件分组(event grouping)、事件预取(event prefetching)等,可以进一步提高应用程序的性能和响应速度。

事件过滤器(Event Filter)则是一种简单的事件处理机制,它允许一个对象拦截并处理其他对象发出的特定类型的事件。事件过滤器通过重载 QObject 类中的两个函数:bool eventFilter(QObject *obj, QEvent *event) 来实现对事件的拦截和处理。当一个对象发出一个事件时,如果该事件符合当前对象正在拦截的事件类型,那么该对象就会调用 eventFilter() 函数进行处理;否则,它会继续将该事件分发给其他对象。

总之,事件分发器和事件过滤器都是用于处理事件的机制,但它们的实现方式和作用不同。事件分发器可以确保同一时间只有一个子对象或父对象接收到同一个事件,并且提供了一些高级功能;而事件过滤器则是一种简单的事件处理机制,允许一个对象拦截并处理其他对象发出的特定类型的事件。

总结

通过一个简单的示例熟悉事件过滤器的工作原理,同时也分析了和事件分发器的区别,相信在后续开发中,也可按照实际需要判断是否需要事件分发或过滤。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值