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:事件相关知识到此结束
相关文章:
Qt:事件
目录 处理事件 鼠标事件 键盘事件 定时器事件 窗口事件 虽然 Qt 是跨平台的 C 开发框架,Qt 的很多能力其实是操作系统提供的 只不过 Qt 封装了系统的 API 事件 前面学习过信号槽: 用户进行的各种操作,就可能会产生出信号,可以…...
python 程序一次启动有两个进程的问题(flask)
0. 背景 写了一个使用 flask 作为服务框架的程序,发现每次启动程序的时候,使用 ps 都能观察到两个 python 进程。 此外,这个程序占用了 GPU 资源,我发现有两个 python 进程,分别占用了完全相同的 GPU 显存 1. 原因 …...
ethtool的资料
ethtoolethtool(8) — Linux manual pageethtool(8) - Linux man pageUsing ethtool in LinuxLooking at your Linux system’s network interface with ethtoolHow to Change Speed & Duplex of Ethernet Card in Linux with ethtool CommandNVIDIA EthtoolRed Hat Enterp…...
SpringBoot过滤器(Filter)的使用:Filter接口、FilterRegistrationBean类配置、@WebFilter注释
1、过滤器(Filter)的介绍 Spring Boot 的过滤器用于对数据进行过滤处理。通过 Spring Boot 的过滤器,程序开发人员不仅可以对用户通过 URL 地址发送的请求进行过滤处理(例如:过滤一些错误的请求或者请求中的敏感词等),而且可以对服务器返回的数据进行过滤处理(例如:压…...
“此电脑”中删除WPS云盘方法(百度网盘通用)
📣此方法适用于卸载WPS云盘后,WPS云盘图标依然在此电脑中显示的问题。 原理:通过注册来进行删除 步骤: WIN键R,打开运行窗口,输入regedit命令,来打开【注册表编辑器】; 从左侧,依…...
Manus AI:开启Agent元年的ChatGPT时刻(附赠资料)
1. Manus AI:全球首个通用Agent Manus AI 是全球首个通用人工智能代理,连接思想与行动,不仅思考,还能交付成果。Manus 擅长处理工作和生活中的各种任务,帮助用户完成一切。其核心理念是“less structure, more intell…...
ChromeDriver下载 最新版本 134.0.6998.35
平时为了下个驱动,到处找挺麻烦,收集了很多无偿分享给需要的人,仅供学习和交流。 ChromeDriver及浏览器134.0.6998.35 ChromeDriver及浏览器133.0.6943.141 ChromeDriver 102.0.5005.61 ChromeDriver 105.0.5195.102 ChromeDriver 108.0…...
Sass进阶之路:@forward 的可见性控制与变量覆盖
文章目录 前言1. 转发导入2. 添加前缀3. 控制可见性4. 转发时修改默认值总结 前言 在上一篇中,我们深入探讨了 use 的使用, 也介绍了 use 在使用深层模块中的变量时具有一定的缺点。所以在本文中,我们将深入解析 forward 的核心用法。 1. 转…...
MySQL作业一
一、创建数据库 #创建数据库 mysql> create database db_ck; Query OK, 1 row affected (0.01 sec)mysql> show databases like "db_%"; ----------------- | Database (db_%) | ----------------- | db_ck | | db_system | ----------------…...
虚拟机总结| 关于虚拟机的一些配置总结
前言 每次安装新的虚拟机都需要重新在网上搜索如何配置网络,我需要写一个自己的部署步骤,增加工作效率,不用每次配置的时候再去网上去翻找。 1.只需要联网功能记录(不固定IP) 1.1 修改ifcfg-ens33 vi etc/sysconfig/network-scripts/ifcfg…...
leetcode-sql数据库面试题冲刺(高频SQL五十题)
题目: 577.员工奖金 表:Employee -------------------- | Column Name | Type | -------------------- | empId | int | | name | varchar | | supervisor | int | | salary | int | -------------------- empId 是该表中具有唯一值的列。 该表的每一行…...
OpenManus:解锁测试工程师的效率密码——实践与应用指南
随着软件行业的快速发展,测试工程师面临的挑战也日益增多:如何在有限的时间内保证产品质量、如何高效生成测试数据、如何快速定位问题根源?这些问题直接影响到产品上线的节奏和用户体验。而在这一背景下,开源项目 OpenManus 的出现…...
Mybatis中的设计模式
1. 工厂模式(Factory Pattern) 概念:工厂模式是一种创建对象的设计模式,它将对象的创建和使用分离,通过一个工厂类来负责创建对象。MyBatis 中的应用:MyBatis 使用 SqlSessionFactory 来创建 SqlSession 对…...
[PWNME 2025] PWN 复现
这种比赛得0也不容易,前边暖声还是能作的。 GOT 指针前溢出,可以溢出到GOT表,然后把后门写上就行 Einstein 这个拿到WP也没复现成,最后自己改了一下。 int __cdecl handle() {int offset; // [rsp8h] [rbp-38h] BYREFunsigne…...
【笔记】记一次easyExcel中注解ExcelProperty映射字段赋值无效问题
背景 最近在开发一个导入excel文件解析数据并入库的功能,导入过程中出现一个BUG:后端映射实体字段pType没有被赋值,但是导入的excel源文件是有数据。 定位问题 经过debug源码发现最终创建对象并赋值使用的是net.sf.cglib.beans.BeanMap类中…...
肖恩的n次根
1.肖恩的n次根 - 蓝桥云课 问题描述 喜欢研究数学问题的肖恩注意到,在编程语言中通常内置函数只有开平方根和开立方根,但是肖思想知道开高次方根(大于3次方称为高次方),应该怎么做。请你设计一个程序来帮帮肖恩。 输…...
《AI浪潮下的创新枢纽:火山引擎大模型应用实验室平台》
《AI浪潮下的创新枢纽:火山引擎大模型应用实验室平台》 引言:AI 时代的新引擎 在科技飞速发展的当下,人工智能(AI)已不再是遥不可及的概念,它如同一股汹涌的浪潮,席卷了我们生活的每一个角落。…...
生成式AI系列(二) LLM生成质量改善的方法——RAG检索增强生成
一、引子 我们需要通过一些手段来提升LLM生成内容质量,主要的有下面三项,本文将主要介绍RAG。 1. 提示工程(Prompt Engineering) 通过精心设计的提示(Prompt)来提升输出的质量 2. 模型微调(Fi…...
Visual studio + Qt 项目配置管理
Visual studio Qt 项目配置管理 1.本机顺利安装 vs 和 Qt 软件 并且设置好Qt 的环境变量比如 E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\bin E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\lib E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\include //这里是你电脑上Qt的路径,每台电脑不一样…...
直装永久授权,最新专业版集成VB7
无论是学生、教师还是职场工作人员,办公软件在日常工作和学习中都是不可或缺的重要工具。在众多办公软件中,微软的Microsoft Office和金山软件的WPS Office最常用的选择。对于许多使用要求不高的小伙伴而言,WPS Office因其易用性和免费版本的…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
