Qt--事件分发器

2023-11-13

写在前面

在 Qt 中,事件分发器(Event Dispatcher)是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从一个对象传递到另一个对象,直到事件被处理或被取消。

每个继承自QObject或QObject的类都可以在本类中重写bool event(QEvent *e),来实现相关事件的捕获和拦截。

事件分发器的工作原理

event函数

每个继承自QObject或QObject的类都可以在本类中重写bool event(QEvent *e),来实现相关事件的捕获和拦截,原型如下:

bool event(QEvent *e);

e: 存储事件相关信息
返回值:返回true表示拦截处理,不再向下分发

这里使用一个简单的示例图帮助理解:
事件分发器
我们知道,没有application应用程序运行后,都有一个事件循环,即exec()。

每个事件都会有一个“四元组”标识事件来自哪个对象,哪个事件触发(信号),要发往哪个对象,使用哪个函数(槽)处理。

而事件分发器则工作在信号发往目的对象的这一阶段,即某一控件对象收到来自事件循环的某一需要该对象处理的事件(信号)时,就会进入到事件分发器,在事件分发器中,可以会有一些事件类型的判断,根据类型进行相应的处理(分发)。

例,在事件分发器中判断,若是鼠标按下事件,则使用mouPressEvent进行专门处理,若是鼠标移动事件,则使用mouseMoveEvent进行相应处理。

可以这样理解:

bool QLabel::event(QEvent* e)
{
	if (是鼠标按下事件)
	{
		//调用mousePressEvent处理,mousePressEvent是虚函数,会动态调用对应版本
		mousePressEvent();
		return true;		//返回true表示成功拦截处理
	}
	else if (鼠标移动事件)
	{
		//同理,调用mouseMoveEvent虚函数进行相应处理
		mouseMoveEvent();
		return true;
	}

	//也可以继续分发给父类处理
	return QFrame::event(e);
}

示例

这里在一个自定义的Label控件中拦截鼠标按下事件:

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);

    //重写鼠标相关事件
    void enterEvent(QEnterEvent *event);

    void leaveEvent(QEvent *event);

    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
    void mouseMoveEvent(QMouseEvent *ev);

    //事件分发器
    bool event(QEvent *e);

signals:

};

#endif // MYLABEL_H

#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>
#include <QEvent>

MyLabel::MyLabel(QWidget *parent)
    : QLabel{parent}
{
    //设置鼠标追踪
    setMouseTracking(true);
}

//重写鼠标相关事件
void MyLabel::enterEvent(QEnterEvent *event)
{
    qDebug() << "鼠标进入";
}

void MyLabel::leaveEvent(QEvent *event)
{
    qDebug() << "鼠标离开";
}



void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    //if (ev->button() == Qt::LeftButton)
    {
        QString qs = QString("鼠标按下, x = %1, y = %2").arg(ev->x()).arg(ev->y());
        qDebug() << qs;
    }

}

void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug() << "鼠标释放";
}

void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{
    //移动需要用buttons函数,位与判断
    if (ev->buttons() & Qt::LeftButton)
    {
        QString qs = QString("鼠标移动了, x = %1, y = %2").arg(ev->x()).arg(ev->y());
        qDebug() << qs;
    }

}

//事件分发器
bool MyLabel::event(QEvent *e)
{
    if (e->type() == QEvent::MouseButtonPress)
    {
        qDebug() << "event 拦截鼠标按下事件";
        return true;
    }

    return QLabel::event(e);
}


运行可以看到成功在event中拦截到鼠标按下事件,而不再继续分发调用mousePressEvent:
拦截鼠标按下事件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt--事件分发器 的相关文章

  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • jQuery隔行变色

  • vant d的地址组件中文操作手册

    vant d的 学习手册 中文操作文档 开发指南 快速上手 基础组件 Empty 空状态 业务组件 地址列表 地址编辑 Area 省市区选择 Card 卡片 Contact 联系人 Coupon 优惠券选择器 GoodsAction 商品导
  • Oracle性能调整的误区

    共享服务器模式 MTS 集群技术 Clustering RAC 分区 并行处理 主要是并行查询 Oracle提供的这些特性确实是用来进行性能改善的 但我们往往忽略了对自身应用特性的分析 它们是否适合于我们 最近 通过对这方面知识的深入了解
  • 简析TCP的三次握手与四次分手原理

    简析TCP的三次握手与四次分手 TCP建立连接过程 第一次握手 建立连接 客户端发送连接请求报文段 将SYN位置为1 Sequence Number为x 然后 客户端进入SYN SEND状态 等待服务器的确认 第二次握手 服务器收到SYN报
  • Linux设备模型4 kobj_attribute

    在上文Linux设备模型 3 Kobject 实例中 我们介绍到如何使用default attribute Default attribute使用很方便 但不够灵活 比如上篇文章在Kobject一节中提到的那个例子 name和val这两个a
  • 单链表的操作(超详细),保证你看完不后悔

    新人小白的博客 希望大家多多关注 一起加油 共同成长 以后会经常更新哒 个人主页 收藏加关注 永远不迷路 数据结构系列 一 顺序表的操作 你真的学会了吗 二 顺序栈的基本操作 三 循环队列的基本操作 你学会了吗 文章目录 数据结构系列 前言
  • 2023浙江省赛“信息安全管理与评估“--Web渗透测试(高职组)

    2022全国职业技能大赛 信息安全管理与评估 高职组 任务书 2022全国职业技能大赛 信息安全管理与评估 任务书 第一阶段竞赛项目试题 第二阶段竞赛项目试题 第三阶段竞赛项目试题 任务2 Web渗透测试 2022全国职业技能大赛 信息安全
  • 发电厂指针仪表检测(YOLOv5训练)

    数据获取 最近在做工业指针仪表检测的项目 自己在网上爬取了3000多张图片 最后经过筛选得到了1214张质量好的图片 自己再进行精心标注 生成VOV格式的xml文件 训练 本人对其用yolov5进行训练后 效果显著 能够精准检测真实场景下仪
  • charles的使用

    一 charles的原理 1 1 Charles的原理 客户端向服务器发起HTTPS请求 Charles拦截客户端的请求 伪装成客户端向服务器进行请求 服务器向 客户端 实际上是Charles 返回服务器的CA证书 Charles拦截服务器
  • SQL学习记录1 --环境搭建, 初识数据库

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 ch00 环境搭建 0 1 MySQL 8 0 的安装 按照提示安装 几乎没遇到问题 有一步显示the specified port is already in use 是和
  • java基础-inputStream两次读取的方法

    场景描述 我们需要对同一个InputStream对象使用多次 比如 客户端从服务器获取数据 利用HttpURLConnection的getInputStream 方法获得Stream对象 需要将InputStream流读取获取相关参数 第一
  • windows消息机制

    windows消息机制 文章目录 windows消息机制 1 创建基本的窗口程序 2 消息传递的原理 1 消息类型 2 消息的传递 3 相应的发送消息的函数SendMessage PostMessage 1 创建基本的窗口程序 基本的窗口程
  • idea项目导入eclipse中步骤

    1 打开eclipse 右键import 找到需要导入的项目 2 重新配置tomcat 已经配置好了建议移除后重新添加 window preference 3 项目上右键 debug AS 发现没有 debug on server 这是没有
  • 【微信小程序】云开发环境的搭建

    准备工作 下载并安装微信开发者工具 微信开发者工具版本 Stable 1 05 2201240 一 双击打开 微信开发者工具 后 点击 新建小程序 二 根据自身项目需求创建小程序项目 注意事项 AppID 即微信小程序的 身份证号码 注册后
  • 初级学习02 Hello world

    1 安装jdk https www oracle com java technologies downloads java8 2 配置环境变量 3 安装notepad https qnw shaid top notepad index ht
  • Gitee搭建自己的图床

    CSDN前段时间的下拉广告和红包雨属实恶心人 现在打算逐步分离文章 而为了避免以后发生更换平台而导致不必要的麻烦 还是把图床单独分离出比较好 图床有商业收费的 如七牛 又拍云 阿里oss数据存储这些 会按空间和流量来收费 高稳定性 适合企业
  • Flutter 使用pageview无缝隙自动轮播教程

    导入要使用的轮播图片 List
  • win10安装cuda11.4及cudnn

    查看nvidia驱动版本 在windows终端键入nvidia smi 查看nvidia显卡驱动 显卡驱动的版本决定了CUDA的版本下限 如果出现上述的问题 则终端进入C Program Files NVIDIA Corporation N
  • Java实现简单的台球桌游戏

    Java实现简单台球桌问题 需求 使小球可以在桌面上移动 移动到桌面边缘将被弹回 显示小区的移动 素材 小球照片 桌球照片 程序源代码 package 桌球游戏 import java awt import javax swing publ
  • Qt--事件分发器

    写在前面 在 Qt 中 事件分发器 Event Dispatcher 是一个核心概念 用于处理 GUI 应用程序中的事件 事件分发器负责将事件从一个对象传递到另一个对象 直到事件被处理或被取消 每个继承自QObject或QObject的类都