Qt:事件

目录

处理事件

鼠标事件

键盘事件

定时器事件

窗口事件


虽然 Qt 是跨平台的 C++ 开发框架,Qt 的很多能力其实是操作系统提供的
只不过 Qt 封装了系统的 API

事件

前面学习过信号槽:
用户进行的各种操作,就可能会产生出信号,可以给某个信号指定槽函数,当信号触发时,就能够自动的执行到对应的槽函数

事件和信号槽非常类似:
用户进行的各种操作,也会产生事件,程序员同样可以给事件关联上处理函数(处理的逻辑),当事件触发的时候,就能够执行到对应的代码

事件本身是操作系统提供的机制,Qt 也同样把操作系统事件机制进行了封装,拿到了 Qt 中
但是由于事件对应的代码编写起来不是很方便,所以 Qt 对于事件机制又进行了进一步的封装,就得到了信号槽

信号槽就是对于事件的进一步封装,事件是信号槽的底层机制

实际 Qt 开发程序过程中,绝大部分和用户之间进行的交互都是通过"信号槽"来完成的
有些特殊情况下,信号槽不一定能搞定(某个用户的动作行为,Qt 没有提供对应的信号)
此时就需要通过重写事件处理函数的形式,来手动处理事件的啊应逻辑

开发事件机制给咱们程序员,咱们就可以根据实际的需要进行更深度的定制化 diy 操作了

用户进行了很多操作,就会产生很多的事件(当然也会产生很多的信号)

下面就是开发中比较典型的事件:

不同场景下,要关注的点是不一样,这些事件的子类中就会包含一些对应的不同的属性


处理事件

让一段代码和某个事件关联起来,当事件触发的时候,就能指定到这段代码
之前信号槽这里通过 connect 来完成上述关联的

对于事件来说,还不太一样:
让当前的类,重写某个事件处理函数,这里用到的是"多态”机制
创建子类, 继承自 Qt 已有的类,在子类中重写父类的事件处理函数
后续事件触发过程中,就会通过多态这样的机制,执行到咱们自己写的子类的函数中

鼠标事件

下面都是创建 QWidget 的,当然也可以创建 QMainWindow,因为用不到工具栏,所以选择的 QWidget

鼠标进入和鼠标离开事件

下面使用上述方式,处理一下鼠标进入(enterEvent)和鼠标离开(leaveEvent)事件:
enterEvent 和 leaveEvent 函数都是虚函数,所以可以被子类重写:

图形化界面的方式创建一个 Label,鼠标进入 Label 时提示 enterEvent,离开时提示 leaveEvent:
为了能清楚看到 Label 的边框,将边框选为 Box

 效果为:

这里需要创建 QLabel 的子类,重写 enterEvent 和 leaveEvent:

类名就叫 Label,父类叫 QLabel:

按照以往的习惯,创建的 Label 类需要有一个父控件,所以在 label.h 中添加:

label.cpp 中添加:


接着在 label.h 中声明两个需要重写的函数:

注意:
要想重写父类的函数,就需要确保你这边写的函数名字和函数的参数列表都完全一致 (形参名无所谓),谨防单词拼写错误

label.cpp 实现:

(void)event 是为了消除警告,因为暂时还没用到 event 这个形参

此时运行程序,鼠标进入和移出 label 时并没有执行上述逻辑,因为:
当前在界面上创建的这个 label 其实是 QLabel,不是咱们自己写的 Label
必须要确保界面上的这个 label 是一个咱们自己定义的 Label 类的实例,才会执行到

右键图形化界面的 label,点击提升为:

输入提升的类名 Label,点击添加,再点击提升:
一定要确保你的类名以及头文件的名字,和上述自定义的类名头文件都匹配

此时右边对象树上面就是 Label 了,没提升前显示是 QLabel:

通过"提升为"这样的方式,就可以把 Qt Designer 中拖上去的控件的类型转换成自定义的控件类型

此时再运行程序,鼠标移入移出 Label 时,就会打印下面的内容了:

此时就说明当前的 enterEvent 和 leaveEvent 这两个事件就被咱们给捕获到了


通过事件获取到鼠标点击的位置

与上面的操作一样,创建一个 Label,再创建一个 Label 类,父类定为 QLabel,并对生成的 Label 的构造函数做一个调整,添加一个 QWidget* 的参数,以便于能够指定父窗口
接着再右键 Label 点击提升为,输入类名后点击提升,此时就完成了提升操作:

下面就是 mousePressEvent 函数,当鼠标按下时就会触发这个函数调用:
左键、右键、滚轮、侧键都能触发

在 label.cpp 中实现 mousePressEvent 函数:

此时鼠标在 Label 范围内点击就会打印 鼠标点击的位置坐标:
上述是以 Label 左上角位置为原点的

下面则是以屏幕左上角为原点获取坐标:

也可以加上下面的代码,来判断按下的是左键还是右键:


通过事件获取到鼠标点击释放按键

与上面的鼠标点击事件一样,下面是重写的 mouseReleaseEvent 函数:

此时就能做到获取鼠标点击释放按键:

clicked 这样的信号,就相当于是一次鼠标按下事件和一次鼠标释放事件


通过事件获取到鼠标双击按键

重写的 mouseDoubleEvent 函数如下:

鼠标第二次按下的时候,才能够识别到是"双击:

注意:
有的程序,可能是单击有一些逻辑,双击有另一些逻辑,如果我们没注意,可能双击操作就能触发单击的逻辑,可能就有 bug


通过事件获取到鼠标移动

刚才重写鼠标事件的操作,都是在自定义的 Labe| 中完成的,此时鼠标只有在 Label 范围内进行动作的时候,才能捕获到
也可以把这些操作直接放到 Widget (QWidqet 子类) 来完成,这样的话,鼠标在整个窗口中进行的各种动作都能获取到了

所以直接在 widget.h widget.cpp 中重写 mouseMoveEvent 函数:

此时运行程序并没有效果

鼠标移动不同于鼠标按下
随便移动一下鼠标,就会产生出大量的鼠标移动事件,当你进行捕获事件的时候,尤其是在这里再进行一些复杂逻辑的时候,程序负担就很重,很容易产生卡顿之类的情况
Qt 为了保证程序的流畅性,默认情况下不会对鼠标移动进行追踪,鼠标移动的时候不会调用mouseMoveEvent,除非显式告诉 Qt 就要追踪鼠标位置

所以需要在 Widget 的构造函数中设置:

此时稍微一动鼠标,就会一直打印,如果移动的比较快,就会明显出现打印卡顿的情况:


通过事件获取到鼠标滚轮的滚动动作

在 QWheelEvent 中 通过 delta() 获取到这次事件鼠标滚轮滚动了多远

同样在 widget.h widget.cpp 中重写 wheelEvent 函数:

滚轮往下滚动就打印 -120,往上滚动就打印 120:

我们也可以在 Widget 类中新增 int total,初始化为0,就能在 wheelEvent 函数中实现统计滚轮滚动的距离了:

效果为:

就可以根据滚轮滚动的操作实现特定的功能,比如可以通过滚轮去缩放字体大小,可以把滚轮滚动的距离映射到具体的数值上,就可以实现类似的效果了


键盘事件

处理键盘按键事件

我们前面学习过的 QShortCut,这是信号槽机制封装过的,获取键盘按键的方式

站在更底层的角度,也可以通过事件获取到当前用户键盘按下的情况

依旧是在 widget.h widget.cpp 中重写 keyPressEvent 函数:

按下 ABCDEF 的效果为,可以发现每一个按钮都对应一个数字:

如果想得知是否按下了具体的某一个键,以 A 为例,代码改为:

也有些场景是组合键 Ctrl + A :


定时器事件

前面学习了QTimer 实现定时器功能
在 QTimer 背后是 QTimerEvent 定时器事件进行支撑的

QObject 提供了一个 timerEvent 这个函数,可以通过定时器,周期性的触发一些操作
里面需要搭配 startTimer 启动定时器,killTimer 关闭定时器 使用

下面通过图形化的方式,拖动一个 LCD Number,初始值改为 10 :

此处 startTimer 的返回值 timerld 类似于 Linux 中的文件描述符,起到的是身份标识的效果

因为后面程序可能还会用到 timerld,所以在 widget.h 中的构造函数定义为类内成员:

在 widget.h widget.cpp 中重写 timerEvent 函数:

运行程序,每隔一秒-1,直到0就停止:

使用 timerEvent 比 QTimer 还是要更复杂一点,手动管理 timerld,还需要区分这次函数调用是哪个 timer 引起的
后续实际开发中,使用 QTimer 即可


窗口事件

  • moveEvent 窗口移动时触发的事件
  • resizeEvent 窗口大小改变时触发的事件

 moveEvent

QMoveEvent 中有下面两个常用的方法:

resizeEvent

QResizeEvent 中有下面两个常用的方法:


在 widget.h widget.cpp 中重写 moveEvent 和 resizeEvent函数:

如果移动 widget 窗口或调整 widget 窗口大小,下面就会打印:


Qt:事件相关知识到此结束

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

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

相关文章

责任链模式:优雅处理复杂流程的设计艺术

引言 在软件设计中,我们经常会遇到需要按特定顺序处理请求的场景。例如,一个订单处理系统可能需要经过验证、付款、物流安排和客户通知等多个步骤。如果我们将这些步骤硬编码在一个方法中,代码将变得臃肿且难以维护。这时,责任链…

【STM32】玩转IIC之驱动MPU6050及姿态解算

目录 前言 一.MPU6050模块介绍 1.1MPU6050简介 1.2 MPU6050的引脚定义 1.3MPU6050寄存器解析 二.MPU6050驱动开发 2.1 配置寄存器 2.2对MPU6050寄存器进行读写 2.2.1 写入寄存器 2.2.2读取寄存器 2.3 初始化MPU6050 2.3.1 设置工作模式 2.3.2 配置采样率 2.3.3 启…

【ThreeJS Basics 09】Debug

文章目录 简介从 dat.GUI 到 lil-gui例子安装 lil-gui 并实例化不同类型的调整改变位置针对非属性的调整复选框颜色 功能/按钮调整几何形状文件夹调整 GUI宽度标题关闭文件夹隐藏按键切换 结论 简介 每一个创意项目的一个基本方面是能够轻松调整。开发人员和参与项目的其他参与…

【Pandas】pandas Series explode

Pandas2.2 Series Computations descriptive stats 方法描述Series.argsort([axis, kind, order, stable])用于返回 Series 中元素排序后的索引位置的方法Series.argmin([axis, skipna])用于返回 Series 中最小值索引位置的方法Series.argmax([axis, skipna])用于返回 Series…

电脑网络出现问题!简单的几种方法解除电脑飞行模式

在某些情况下,您可能需要关闭电脑上的飞行模式以便重新连接到 Wi-Fi、蓝牙或其他无线网络。本教程中简鹿办公将指导您如何在 Windows 和 macO S操作系统上解除飞行模式。 一、Windows 系统下解除飞行模式 通过快捷操作中心 步骤一:点击屏幕右下角的通知…

nature genetics | SCENT:单细胞多模态数据揭示组织特异性增强子基因图谱,并可识别致病等位基因

–https://doi.org/10.1038/s41588-024-01682-1 Tissue-specific enhancer–gene maps from multimodal single-cell data identify causal disease alleles 研究团队和单位 Alkes L. Price–Broad Institute of MIT and Harvard Soumya Raychaudhuri–Harvard Medical S…

MyBatis-Plus 与 Spring Boot 的最佳实践

在现代 Java 开发中,MyBatis-Plus 和 Spring Boot 的结合已经成为了一种非常流行的技术栈。MyBatis-Plus 是 MyBatis 的增强工具,提供了许多便捷的功能,而 Spring Boot 则简化了 Spring 应用的开发流程。本文将探讨如何将 MyBatis-Plus 与 Spring Boot 进行整合,并分享一些…

uploadlabs通关思路

目录 靶场准备 复现 pass-01 代码审计 执行逻辑 文件上传 方法一:直接修改或删除js脚本 方法二:修改文件后缀 pass-02 代码审计 文件上传 1. 思路 2. 实操 pass-03 代码审计 过程: 文件上传 pass-04 代码审计 文件上传 p…

AI编程工具节选

1、文心快码 百度基于文心大模型推出的一款智能编码助手, 官网地址:文心快码(Baidu Comate)更懂你的智能代码助手 2、通义灵码 阿里云出品的一款基于通义大模型的智能编码辅助工具, 官网地址:通义灵码_你的智能编码助手-阿里云 …

目录扫描工具深度对比:Dirb、Dirsearch、DirBuster、Feroxbuster 与 Gobuster

✨ 前言 在网络安全测试与渗透测试中,目录扫描(又称目录枚举)是一项至关重要的技术。它用于发现 Web 服务器上未公开的隐藏目录和文件,这些资源可能包含敏感数据、配置文件甚至潜在漏洞,因而成为攻击者与安全研究人员…

“双碳”背景下,企业应该如何提升能源效率?

在当今竞争激烈的市场环境中,企业不仅需要优化成本,还需积极响应国家的能源政策,减少对环境的影响。提升工业能源效率正是实现这一双重目标的关键。中国近年来大力推进“双碳”目标(碳达峰、碳中和),并出台…

无人机扩频技术对比!

一、技术原理与核心差异 FHSS(跳频扩频) 核心原理:通过伪随机序列控制载波频率在多个频点上快速跳变,收发双方需同步跳频序列。信号在某一时刻仅占用窄带频谱,但整体覆盖宽频带。 技术特点: 抗干扰…

当AI开始“思考“:拆解大模型训练与推理的秘密(以DeepSeek为例)

如果你用过deepseek,可能体验过它在几秒内编故事、写代码的震撼。但你是否想过,这种"智能输出"背后存在两种完全不同的底层机制?就像人类需要先学习知识(训练)才能考试答题(推理)&…

永洪科技深度分析实战,零售企业的销量预测

随着人工智能技术的不断发展,智能预测已经成为各个领域的重要应用之一。现在,智能预测技术已经广泛应用于金融、零售、医疗、能源等领域,为企业和个人提供决策支持。 智能预测技术通过分析大量的数据,利用机器学习和深度学习算法…

Vue项目通过内嵌iframe访问另一个vue页面,获取token适配后端鉴权(以内嵌若依项目举例)

1. 改造子Vue项目进行适配(ruoyi举例) (1) 在路由文件添加需要被外链的vue页面配置 // 若依项目的话是 router/index.js文件 {path: /contrast,component: () > import(/views/contrast/index),hidden: true },(2) 开放白名单 // 若依项目的话是 permission.js 文件 cons…

【DeepSeek】5分钟快速实现本地化部署教程

一、快捷部署 (1)下载ds大模型安装助手,下载后直接点击快速安装即可。 https://file-cdn-deepseek.fanqiesoft.cn/deepseek/deepseek_28348_st.exe (2)打开软件,点击立即激活 (3)选…

Linux第一课

如何在Windows系统上安装红帽Linux虚拟机 一:下载VNware 下载链接:Desktop Hypervisor Solutions | VMware 二:下载操作系统镜像文件 在阿里云开源镜像站下载(本文章下载 red hat 9.3) 阿里云开源镜像站链接:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 三:创建虚拟机文…

语音分离:使用短时能量提取主声源

语音分离模型:mossfomer2 计算短时能量 def compute_short_time_energy(audio: np.ndarray, frame_size: int, hop_size: int) -> np.ndarray:"""计算音频信号的短时能量 将音频分为若干帧,每一帧长度为 frame_size, 帧与帧之间以 h…

【VUE】第二期——生命周期及工程化

目录 1 生命周期 1.1 介绍 1.2 钩子 2 可视化图表库 3 脚手架Vue CLI 3.1 使用步骤 3.2 项目目录介绍 3.3 main.js入口文件代码介绍 4 组件化开发 4.1 组件 4.2 普通组件注册 4.2.1 局部注册 4.2.2 全局注册 1 生命周期 1.1 介绍 Vue生命周期:就是…

SyntaxError: Unexpected keyword ‘else‘

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…