一个Qt鼠标透传场景与事件过滤器的用法

news2024/10/5 14:25:36

一个Qt鼠标透传场景与事件过滤器的用法

最近工作中遇到一个开发场景,将一个QWidget控件(称为控件A)放入QScrollArea,该控件A重写了QWidget::wheelEvent,根据鼠标滚轮事件缩放内部的绘制视图。当控件过大时,QScrollArea的滚动条出现,此时鼠标滚动也会触发页面滚动,用一个Demo演示:
在这里插入图片描述

问题

对于这个体验问题,提出了一个方案,当按住Ctrl并滚动滚轮,执行控件A的触发缩放逻辑;当没有按Ctrl时,仅滚动页面。但是,由于该控件A是第三方库创建的,无法重写事件处理,所以只能借助Qt事件过滤器或者其他方案。

分析

出现该问题的原因是,控件A重写QWidget::wheelEvent处理缩放,没有将QWheelEvent设置为accepted,即标记为已处理,而Qt对于输入事件(鼠标、键盘等),如果目标控件没有处理,则会将事件投递给其父控件。

因此需要通过事件过滤器,处理控件A的逻辑,不继续透传事件,或者直接透传事件。

基本事件分发流程

Qt分发事件的总入口在QApplication::notify,事件在这里被分发给目标控件。事件分发后,对于Qt的鼠标等事件,会根据事件是否被处理(即QEvent::isAccepted),将未处理的事件透传给当前控件的父控件,或者称之为冒泡。直到其中一个父级控件处理,事件停止透传。

事件分发给目标控件前,会查找目标控件安装的事件过滤器(通过QObject::installEventFilter注册)对象,并按顺序调用其QObject::eventFilter。该方法返回bool值,true则直接返回到QApplication::notify,后续的事件过滤器对象也就不再被调用。

如果所有的事件过滤器对象(QObject::eventFilter)都返回false,则会调用目标控件的QObject::event。对于QWidget,此时会根据事件类型,调用对应的事件处理函数(如 QWidget::wheelEvent)。不同的Qt控件,可能也会重写QWidget::event,在调用其事件处理函数前,执行一些逻辑。

解决方法

首先控件A安装事件过滤器到任意QObject对象,重写该对象的eventFilter方法:

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::Wheel && watched == target)
    {
        if(static_cast<QWheelEvent*>(event)->modifiers() & Qt::CTRL)
        {
            watched->event(event); 	// 1
            event->accept();		// 2
            return true;			// 3
        }
        else
        {
            event->ignore();		// 4
            return true;			// 5
        }
    }
    return false;	// 原则上应该调用父类的eventFilter。如果父类没有被安装过滤器,直接false即可
}

代码解释:

  • 1,直接调用QObject::event接口。因为QWidget::event重写时改成protected
  • 2、3,标记事件已被处理,并返回true。按上面说的事件分发流程,回到QApplication::notify,由于事件被处理,鼠标滚轮事件不再继续透传给父控件,分发中断。
  • 4、5,标记事件未处理,返回true,同样回到QApplication::notify,事件透传给父控件。因此跳过了当前控件的处理逻辑。

最终效果

在这里插入图片描述

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

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

相关文章

软件工程评级B-,有大量调剂名额。北京联合大学考情分析

北京联合大学(B-) 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1239字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 北京…

FreeMarker详细介绍

FreeMarker详细介绍 FreeMarker FreeMarker概述 FreeMarker概念 FreeMarker 是一款 模板引擎&#xff1a; 即一种基于模板和要改变的数据&#xff0c; 并用来生成输出文本(HTML网页&#xff0c;电子邮件&#xff0c;配置文件&#xff0c;源代码等)的通用工具。 是一个Java类库…

nodejs实现websocket服务端和客户端

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

MySQL长文本字段的选取

某个字段需要存储 长文本类型的数据,长度可变,范围不清. varchar最多能存储多大长度呢? 何种情况下用text更好? 以下内容就为探究这个问题: <1>.先将content字段设为varchar(255),则此字段只能最多存储255个字符数 package mainimport "fmt"func main() { va…

2023年会展行业研究报告

第一章 行业概况 1.1 定义 会展行业是一个多元化和复杂的领域&#xff0c;涵盖了许多不同的活动和功能。一般来说&#xff0c;会展业是指在一定的区域空间内&#xff0c;许多人聚集在一起形成的定期或者不定期&#xff0c;制度或者非制度&#xff0c;传递和交流信息的群众性的…

Visual Studio运行Python程序(超级详细)

Visual Studio Code&#xff0c;简称 VS Code&#xff0c;是由微软公司开发的 IDE 工具。与微软其他 IDE&#xff08;如 Visual Studio&#xff09;不同的是&#xff0c;Visual Studio Code 是跨平台的&#xff0c;可以安装在 Windows、Linux 和 macOS平台上运行。 不仅如此&am…

UMA 2 - 创建自己的UMA模型⭐一.配置Blender环境

文章目录 🟥 下载 simple_renaming_panel🟧 Blender安装插件🟨 启用插件并保持自动更新🟩 打开插件视图🟥 下载 simple_renaming_panel UMA需要指定的人物骨骼名称,因此我们用该Blender插件快捷重命名. 下载链接: https://github.com/Weisl/simple_renaming_panel �…

阅读类APP广告变现的商业化发展方向

免费阅读类 APP 对广告的依赖程度较高。因此&#xff0c;如何实现流量精细化运营以最大化流量价值&#xff0c;是流量主面临的关键课题和难点&#xff1b;与此同时&#xff0c;免费阅读 APP 的 PV 量极大&#xff0c;但 UV、DAU 量级相对较小&#xff0c;因此&#xff0c;如何开…

python 学习笔记(6)—— Flask 、MySql

目录 Flask 1、起步 2、渲染项目的首页 3、处理无参数的 GET 请求 4、处理有 query 参数的 GET 请求 6、处理 params 参数的 get 请求 6、处理 application/json 类型请求体的 POST 请求 7、根据参数渲染模板页面 8、上传文件 数据库操作&#xff08;mysql&#xff0…

Jenkins结合gitlab自动化持续集成

最近在公司有负责搭建自动化测试环境&#xff0c;自动化脚本写好后&#xff0c;毋庸置疑是需要将自动化脚本进行持续集成测试&#xff0c;能够根据企业的定制化需求&#xff0c;通过Jenkins触发执行构建任务&#xff0c;定时执行自动化脚本等&#xff0c;今天就给大家介绍一下J…

可视化大屏设计模板 | 主题皮肤(报表UI设计)

下载使用可视化大屏设计模板&#xff0c;减少重复性操作&#xff0c;提高报表制作效率的同时也确保了报表风格一致&#xff0c;凸显关键数据信息。 软件&#xff1a;奥威BI系统&#xff0c;又称奥威BI数据可视化工具 所属功能板块&#xff1a;主题皮肤上传下载&#xff08;数…

【实践篇】redis管道pipeline使用详解

文章目录 0. 前言什么场景下使用redis管道特性 1.原理1.1 redis管道特性的处理机制 使用redis管道优化示例3. springboot使用redis管道示例4. 参考资料5. 源码地址6. Redis从入门到精通系列文章 0. 前言 Redis管道&#xff08;Pipeline&#xff09;是一种批量执行Redis命令的机…

Revit SDK 介绍:TypeRegeneration 修改类型,更新文档 ValidateParameters 参数合法性验证

前言 这篇文章介绍两个例子&#xff0c;逻辑比较简单&#xff1a; TypeRegeneration 修改类型&#xff0c;更新文档ValidateParameters 参数合法性验证 内容 TypeRegeneration FamilyType 不是继承自 Element 的&#xff0c;而是独立于 Element 体系之外&#xff0c;直接从…

window.structuredClone()

先看下兼容性 1. 创建一个要克隆的对象。例如&#xff1a; const originalObj {name: John,age: 25,address: {city: New York,country: USA} };2. 调用structuredClone()方法克隆对象。例如&#xff1a; const clonedObj window.structuredClone(originalObj);3. clonedObj将…

软件安全研究(四)

文章目录 Fine-Grained Code Clone Detection with Block-Based Splitting of Abstract Syntax Tree文章结构IntroMotivationDefinitionSystemOverviewProcessingVerify Experimentexperimental settingsRQ1RQ2RQ3RQ4RQ5 Fine-Grained Code Clone Detection with Block-Based S…

MeterSphere压测,出现HttpHostConnectException

现象&#xff1a;MeterSphere更换压力机后&#xff0c;压测出现出现HttpHostConnectException 解决方案&#xff1a; net.ipv4.tcp_tw_reuse默认是0或者2&#xff0c;更改为1 net.ipv4.tcp_tw_reuse&#xff0c;表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连…

轻量级软件FastGithub实现稳定访问github

当我们想访问全球最大的“同性交友网站”https://github.com/ 时&#xff0c;总会出现无法访问的界面&#xff0c;令人非常苦恼&#xff1a;幸运的是&#xff0c;有一种轻量级的软件可以帮助我们稳定地访问GitHub&#xff0c;那就是FastGithub。 什么是FastGithub&#xff1f…

数据结构和算法(5):二叉树

树 向量允许通过下标或秩&#xff0c;在常数的时间内找到目标对象&#xff1b;然而&#xff0c;一旦需要对这类结构进行修改&#xff0c;那么无论是插入还是删除&#xff0c;都需要耗费线性的时间。 列表允许借助引用或位置对象&#xff0c;在常数的时间内插入或删除元素&…

去除pdf/word的水印艺术字

对于pdf中的水印如果无法去除水印&#xff0c;则先另存为word&#xff0c;然后再按下面办法处理即可&#xff1a; 查看宏&#xff0c;创建&#xff1a;删除艺术字 添加内容&#xff1a; Sub 删除艺术字()Dim sh As ShapeFor Each sh In ActiveDocument.ShapesIf sh.Type msoT…

用ASE制作地表积水效果

unity引擎制作实时刷下雨地面效果 大家好&#xff0c;我是阿赵。   之前在Unity引擎做了几种不同的效果&#xff0c;比如视差偏移、下雨效果、顶点颜色工具等。这一篇文章&#xff0c;将会把这几个效果合并在一起&#xff0c;做出一个混合积水地表的效果。这个几个shader的基…