【QT】事件分发器 事件过滤器

news2024/9/19 13:13:44

qt 系统 - 事件分发器 and 事件过滤器

  • 一、事件分发器
    • 1. 事件分发器概念
    • 2. 事件分发器工作原理
  • 二、事件过滤器

一、事件分发器

1. 事件分发器概念

在 Qt 中,事件分发器(Event Dispatcher) 是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。

2. 事件分发器工作原理

在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event() 函数。所有的事件都会进入到这个函数里面,那么我们处理事件就要重写这个 event() 函数。event() 函数本⾝不会去处理事件,而是根据 事件类型(type值)调用不同的事件处理函数。事件分发器就是工
作在应用程序向下分发事件的过程中,如下图:

在这里插入图片描述

如上图,事件分发器⽤于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e) 函数来实现。其返回值为布尔类型,若为 ture,代表拦截,不向下分发。

Qt 中的事件是封装在 QEvent 类中,在 Qt 助手中输入 QEvent 可以查看其所包括的事件类型,如下图示:

在这里插入图片描述

在这里插入图片描述

示例代码:

1、在 “widget.h” 头⽂件中声明 ⿏标点击事件 和 事件分发器;如下图⽰:

			class Widget : public QWidget
			{
			    Q_OBJECT
			
			public:
			    Widget(QWidget *parent = nullptr);
			    ~Widget();
			
			    // 鼠标点击事件
			    void mousePressEvent(QMouseEvent* event);
			
			    // 通过事件分发器拦截鼠标按下事件
			    bool event(QEvent* event);
			
			private:
			    Ui::Widget *ui;
			};

2、在 “widget.cpp” ⽂件中实现 ⿏标点击事件 和 拦截事件;

			#include <QDebug>
			#include <QMouseEvent>
			void Widget::mousePressEvent(QMouseEvent *event)
			{
			    if(event->button() == Qt::LeftButton) {
			        qDebug() << "鼠标左键被按下!";
			    }
			}
			
			bool Widget::event(QEvent *event)
			{
			    if(event->type() == QEvent::MouseButtonPress) {
			        qDebug() << "Event 中鼠标被按下!";
			        return true; // return true 代表不向下分发
			    }
			    // 其它事件交给父类处理(默认处理)
			    return false;
			}

执行效果如下,当鼠标左键点击窗口时,就会执行 event 函数,而不会执行 mousePressEvent 函数:

在这里插入图片描述

二、事件过滤器

在 Qt 中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。通过上面的学习,我们已经知道,Qt 创建了 QEvent 事件对象之后,会调用 QObjectevent() 函数处理事件的分发。显然,我们可以在 event() 函数 中实现拦
截的操作。由于 event() 函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个 event() 函数。这当然相当麻烦,更不用说重写 event() 函数还得小心一堆问题。好在 Qt 提供了另外⼀种机制来达到这一目的:事件过滤器

事件过滤器是在应用程序分发到 event 事件分发器之前,再做⼀次更高级的拦截。如下图示:

在这里插入图片描述

事件过滤器的⼀般使用步骤:

  • 安装事件过滤器;
  • 重写事件过滤器函数:eventfilter()

代码示例:

1、设计 UI 文件,拖入一个 label,如下图示;

在这里插入图片描述

3、在项目新添加⼀个类:MyLabel

先选中项目名称 QEvent_2,点击⿏标右键,选择 add new … ,弹出如下对话框,选择 Choose 即可:

在这里插入图片描述

4、选择:Choose … 后,弹出如下界面,按照如下形式创建即可:

在这里插入图片描述

5、此时项目中会新添加我们刚新建的头文件和cpp文件;
6、在 UI 文件中选中 Label,右键 ------> 提升为…;当点击 "提升为… " 之后,弹出如下对话框:

在这里插入图片描述

接下来按照下图选择即可:

在这里插入图片描述

7、在 “mylabel.h” 中声明 ⿏标点击事件 和 事件分发器:

			#include <QWidget>
			#include <QLabel>
			
			class myLabel : public QLabel
			{
			    Q_OBJECT
			public:
			    explicit myLabel(QWidget *parent = nullptr);
			    
			    // 鼠标点击事件
			    void mousePressEvent(QMouseEvent* event);
			    
			    // 事件分发器
			    bool event(QEvent* e);
			};

8、在 “mylabel.cpp” ⽂件中实现⿏标点击事件和事件分发器;

			#include <QMouseEvent>
			#include <QDebug>
			
			myLabel::myLabel(QWidget *parent) : QLabel(parent)
			{}
			
			void myLabel::mousePressEvent(QMouseEvent *event)
			{
			    QString str = QString("鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());
			    qDebug() << str.toUtf8().data();
			}
			
			bool myLabel::event(QEvent *e)
			{
			    // 如果是鼠标按下,在event事件分发时拦截操作
			    if(e->type() == QEvent::MouseButtonPress) {
			        QMouseEvent* event = static_cast<QMouseEvent*>(e);
			        QString str = QString("Event 函数中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());
			        qDebug() << str.toUtf8().data();
			
			        return true; // 返回true,代表用户自己处理,不向下分发
			    }
			
			    return QLabel::event(e); // 其他事件交给父类处理
			}

9、在 “widget.h” 头文件中声明事件过滤器函数;

			class Widget : public QWidget
			{
			    Q_OBJECT
			
			public:
			    Widget(QWidget *parent = nullptr);
			    ~Widget();
			    
			    // 声明 eventfilter 事件
			    bool eventFilter(QObject* obj, QEvent* e);
			
			private:
			    Ui::Widget *ui;
			};

10、在 “widget.cpp” ⽂件中实现事件过滤器的两个步骤;

			#include <QEvent>
			#include <QMouseEvent>
			#include <QDebug>
			
			Widget::Widget(QWidget *parent)
			    : QWidget(parent)
			    , ui(new Ui::Widget)
			{
			    ui->setupUi(this);
			    
			    // 1. 给label安装事件过滤器,this:当前窗口安装事件过滤器
			    ui->label->installEventFilter(this);
			}
			
			// 2. 重写eventfilter事件
			bool Widget::eventFilter(QObject *obj, QEvent *e)
			{
			    // 判断控件
			    if(obj == ui->label) {
			        if(e->type() == QEvent::MouseButtonPress) {
			            QMouseEvent* event = static_cast<QMouseEvent*>(e);
			            QString str = QString("事件过滤器中鼠标按下:x = %1, y = %2").arg(event->x()).arg(event->y());
			            qDebug() << str.toUtf8().data();
			            
			            return true;
			        }
			    }
			    // 其它交给父类处理
			    return QWidget::eventFilter(obj, e);
			}

执行效果如下,当在标签中点击鼠标时不会执行 event 函数,而会执行 eventfilter 函数:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java黑色界面陪玩高端小程序源码陪练APP源码H5公众号源码电竞系统

&#x1f680;【电竞新纪元】解锁高端陪玩小程序源码 & 陪练APP秘籍&#xff0c;H5公众号全攻略&#xff01; &#x1f3ae; 开篇&#xff1a;电竞热潮下的新机遇 Hey游戏迷们&#xff01;随着电竞行业的蓬勃发展&#xff0c;你是否也想在这股浪潮中分得一杯羹&#xff1…

opencascade AIS_Manipulator源码学习

前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类&#xff0c;用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式&#xff0c;使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类&#xff0c;通过鼠标操控另一个交互对象…

新手网站利用好网站地图,提高网站的pr和权重

新手网站利用好网站地图&#xff0c;提高网站的pr和权重 它能引导蜘蛛更好的抓取收录我们网站的资源&#xff0c;从而提高网站的pr和权重。但网站地图的更新是个费神费力的工作&#xff0c;对于站长&#xff0c;尤其是精力有限的草根站长&#xff0c;怎样才能将有限的时间发挥出…

DDoS 究竟在攻击什么?

分布式拒绝服务&#xff08;DDoS&#xff09;攻击是一种常见的网络攻击形式&#xff0c;攻击者通过向目标服务端发送大量的请求&#xff0c;使目标服务端无法进行网络连接&#xff0c;无法正常提供服务。 DDoS 攻击通常是由大量的分布在全球各地的 “僵尸” 计算机&#xff08…

c++ 求解质因数(细节详解)

定义 这里先来了解几个定义&#xff08;如已了解&#xff0c;可直接看下一个板块&#xff09; 因数&#xff1a;又称为约数&#xff0c;如果整数a除以整数b&#xff08;b0&#xff09;的商正好是是整数而没有余数&#xff0c;我们就说b是a的因数 质数&#xff1a;又称为素数…

免费HTTPS代理的风险与网站推荐

在当今的网络环境中&#xff0c;免费HTTPS代理服务因其“零成本”的特点吸引了不少用户。然而&#xff0c;免费往往意味着某些隐性的代价。作为专业的测评团队&#xff0c;我们深入探索了市场上的免费HTTPS代理服务&#xff0c;并在此提醒大家注意其中的风险&#xff0c;同时推…

【企业级开发模型】Git分支设计模型 | 企业级项目挂历实战_准备工作开发场景实操

目录 3.Git分支设计模型 3.1master分支 3.2release分支 3.3develop分支 3.4feature分支 3.5hotfix分支 4.企业级项目挂历实战_准备工作&开发场景实操学习文档 3.Git分支设计模型 对于我们开发人员来说&#xff0c;对于不同的场景/环境&#xff0c;来设计分支模型。…

Redis与MySQL数据一致性问题的策略模式及解决方案

目录 一、策略模式 1、旁路缓存模式&#xff08;Cache Aside Pattern&#xff09; 2、读写穿透&#xff08;Read-Through/Write-Through&#xff09; 3、异步缓存写入&#xff08;Write Behind&#xff09; 二、一致性解决方案 1、缓存延迟双删 2、删除重试机制 3、读取…

30.【C语言】函数系列下

1.嵌套调用 *定义&#xff1a;函数之间的互相调用 *例&#xff1a; int function1(int a, int b) {function2(b);//嵌套函数的调用return a; } //注意&#xff1a;不能将function2定义在function1的里面&#xff0c;这不叫嵌套函数的调用 void function2(int c) {} #include…

聊一聊 Node.js(Express)的 req.body、req.params 和 req.query 区别和应用场景

在Node.js的Express框架中&#xff0c;处理客户端发送到服务器的数据时&#xff0c;我们主要使用req.body、req.params和req.query三个属性。这些属性虽然都是请求对象(req)的一部分&#xff0c;但它们的数据来源和用途却各不相同。本文将为大家详细解读它们的区别和使用方法。…

AI绘画SD中 ControlNet 组件 IP-Adapter 实现风格迁移,AI绘画垫图神器!

大家好&#xff0c;我是画画的小强 今天给大家介绍一下AI绘画SD中ControlNet 的 IP-Adapter 组件&#xff0c;该组件可以方便快捷的帮我们对图片的风格进行迁移&#xff0c;简而言之就是可以参考你放置的图片风格来生成其他图片。 它的效果和reference only有点类似&#xff…

LabVIEW 实现用户授权与管理多项测试项目

在使用 LabVIEW 开发测试软件时&#xff0c;用户授权和项目管理是一个重要的功能。为了确保系统安全性、灵活性和可扩展性&#xff0c;可以设计一个用户管理系统&#xff0c;允许管理员增加或减少用户的测试项目权限。以下是一个详细的实现方案&#xff0c;包括用户授权管理、项…

vue字段判断是否可以鼠标悬浮或者点击跳转

通过字段判断是否可以鼠标悬浮展示颜色 是否点击 <span :class"[converBond.stkindustry ! null ? hoverSpan:,]"click"converBond.stkindustry ! null ?goToIndustry(converBond.stkindustryname,converBond.stkindustry):false">{{converBon…

【星地多网融合调度平台】——打造全方位、立体化的应急通信网络

在复杂的应急场景下&#xff0c;信息的快速传递与指挥调度显得尤为重要。星地多网融合调度指挥箱&#xff0c;凭借其强大的多网融合能力&#xff0c;确保了指挥中心与前线救援队伍之间的信息流畅&#xff0c;无论是位置追踪、应急通信&#xff0c;还是全方位视频监控&#xff0…

数仓架构解析(第45天)

系列文章目录 经典数仓架构传统离线大数据架构 文章目录 系列文章目录烂橙子-终生成长社群群主&#xff0c;前言1. 经典数仓架构2. 传统离线大数据架构 烂橙子-终生成长社群群主&#xff0c; 采取邀约模式&#xff0c;不支持付费进入。 前言 经典数仓架构 传统离线大数据架…

细说MCU用单路DAC模块设计和输出锯齿波的实现方法

目录 一、STM32G474RE的DAC模块 二、配置 1.配置DAC 2.选择时钟源和Debug 3.配置系统时钟 三、代码修改 1.启动DAC 2.给DAC的数据输出寄存器赋值 3.运行并观察输出 一、STM32G474RE的DAC模块 有些MCU本身就带有数/模转换器(Digital to Analog Converter,DAC)模块&am…

netty入门-3 EventLoop和EventLoopGroup,简单的服务器实现

文章目录 EventLoop和EventLoopGroup服务器与客户端基本使用增加非NIO工人NioEventLoop 处理普通任务与定时任务 结语 EventLoop和EventLoopGroup 二者大概是什么这里不再赘述&#xff0c;前一篇已简述过。 不理解也没关系。 下面会简单使用&#xff0c;看了就能明白是什么 这…

加速决策过程:企业级爬虫平台的实时数据分析

摘要 在当今数据驱动的商业环境中&#xff0c;企业如何才能在海量信息中迅速做出精准决策&#xff1f;本文将探讨企业级爬虫平台如何通过实时数据分析加速决策过程&#xff0c;实现数据到决策的无缝衔接。我们聚焦于技术如何赋能企业&#xff0c;提升数据处理效率&#xff0c;…

深入分析 Android ContentProvider (三)

文章目录 深入分析 Android ContentProvider (三)ContentProvider 的高级使用和性能优化1. 高级使用场景1.1. 数据分页加载示例&#xff1a;分页加载 1.2. 使用 Loader 实现异步加载示例&#xff1a;使用 CursorLoader 加载数据 1.3. ContentProvider 与权限管理示例&#xff1…

On the Dimensionality of Word Embedding论文解读

基本信息 作者Zi Yindoi10.3115/v1/D14-1162发表时间2018期刊NIPS网址https://arxiv.org/abs/1812.04224 研究背景 1. What’s known 既往研究已证实 词嵌入的一元不变性。 多数的词嵌入算法本质上都是矩阵分解。 2. What’s new 创新点 提出了 Pairwise Inner Product&…