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# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • 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的类都