16. Qt系统相关:事件、定时器

news2025/5/9 12:50:28

1. Qt事件

1.1 简介

        事件是应用程序内部或者外部产生的事情或者动作的统称。在Qt中使用一个对象来表示一个事件。所有的Qt事件均继承于抽象类QEvent。事件是由系统或者Qt平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件是在用户操作时发出,如键盘事件、鼠标事件等,另一些则是由系统本身自动发出,如定时器事件。常见的Qt事件如下:

常见事件描述:

1.2 事件处理

        事件处理一般常用的方法为:重写相关的Event函数。

        在Qt中,几乎所有的Event函数都是虚函数,所以可以重新实现。比如鼠标的进入和离开事件,通过重写enterEvent()和leaveEvent()函数实现。

1.3 鼠标事件

1.3.1 鼠标进入&离开事件

        继承实现鼠标进入、离开事件函数:

virtual void enterEvent(QEnterEvent *event);
    virtual void leaveEvent(QEvent *event);

        例如我们需要获取某个控件的鼠标进入、离开事件,就可以继承对应的控件类,实现enterEvent、leaveEvent接口,实现我们自定义的事件处理操作。

        在ui界面上,右键对应的控件,通过提升操作,将其提升为我们实现的类,即可快速实现界面控件替换为我们实现的控件类。

1.3.2 鼠标点击事件

virtual void mousePressEvent(QMouseEvent *event)

注意:鼠标上左键、右键、鼠标滚轮按下、前进/后退侧键,都能触发mousePressEvent事件

(1)获取鼠标点击时坐标

  • 坐标原点为当前控件左上角:

inline int QMouseEvent::x() const

inline int QMouseEvent::y() const

  • 坐标原点为整个屏幕左上角:

 inline int QMouseEvent::globalX() const

 inline int QMouseEvent::globalY() const

(2)获取触发该事件的按键类型

inline Qt::MouseButton button() const

1.3.3 鼠标释放事件

virtual void mouseReleaseEvent(QMouseEvent *event)

1.3.4 鼠标双击事件

virtual void mouseDoubleClickEvent(QMouseEvent *event)

注意:双击操作也会触发单击事件

1.3.5 鼠标移动事件

virtual void mouseMoveEvent(QMouseEvent *event)

注意:随意的鼠标移动,会触发大量的鼠标移动事件,如果多事件进行捕获、进行一些逻辑操作,可能导致程序卡顿等情况,所以Qt为了保证程序流畅性,默认不会开启鼠标移动事件追踪,也就是不会调用mouseMoveEvent接口。

开启鼠标移动事件追踪:

inline void QWidget::setMouseTracking(bool enable)

1.3.6 鼠标滚轮事件

virtual void QWidget::wheelEvent(QWheelEvent *event)

获取滚轮滚动信息:

 inline QPoint angleDelta() const

获取滚轮滚动长度(正负表示方向):

1.4 键盘事件

        Qt中的按键事件是通过QKeyEvent类来实现的,当键盘上的按键被按下或者释放时,键盘事件便会触发。

注意:只有当控件获取到焦点时,该控件的键盘事件才会被触发。

1.4.1 单个按键

virtual void keyPressEvent(QKeyEvent *event);

1.4.2 组合按键

        Qt::KeyboardModifier 中定义了在处理键盘事件时对应的修改键。在 Qt 中,键盘事件可以与修改键⼀起使⽤,以实现⼀些复杂的交互操作。KeyboardModifier 中修改键的具体描述如下:

示例:判断是否按下ctrl+A组合键

1.5 窗口事件

1.5.1 窗口移动事件

 virtual void moveEvent(QMoveEvent *event);

QMoveEvent核心接口:

inline const QPoint &pos() const { return m_pos; }
inline const QPoint &oldPos() const { return m_oldPos;}

1.5.2 窗口大小改变事件

 virtual void resizeEvent(QResizeEvent *event);

QResizeEvent核心接口:

inline const QSize &size() const { return m_size; }
inline const QSize &oldSize()const { return m_oldSize;}

2. Qt定时器

        Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定 时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀个任务。定时器在很多场景下都会 使⽤到,如弹窗⾃动关闭之类的功能等。

Qt中的定时器分为 QTimerEvent QTimer 这2个类。

QTimerEvent类 用来描述⼀个定时器事件。在使⽤时需要通过 startTimer() 函数来开启⼀个定时

器,这个函数需要输⼊⼀个以毫秒为单位的整数作为参数来表明设定的时间,它返回的整型值代表

这个定时器。当定时器溢出时(即定时时间到达)就可以在 timerEvent() 函数中获取该定时器的

编号来进⾏相关操作。

QTimer类 来实现⼀个定时器,它提供了更⾼层次的编程接⼝,如:可以使⽤信号和槽,还可以设置只运⾏⼀次的定时器。

2.1 QTimerEvent

        QTimerEvent继承自QEvent,QObject提供了事件的接收和派发,可以直接实现QObject的

void timerEvent(QTimerEvent *event)

接口,来接收并处理TimerEvent事件。

        QObject中也实现了创建开始定时器和关闭定时器的接口,方便快速实现定时器效果:

int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);

int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer);
void killTimer(int id);

注意:一个程序内多个定时器都会触发TimerEven事件,所以需要TimerId来标识某一个定时器,在事件处理接口中,通过QTimerEvent的timerId()接口获取触发本次事件的定时器id。

2.2 QTimer

        QTimer可以让我们更加方便快速的实现定时器效果,并利用信号槽机制来处理timeout事件。

3. 事件分发器

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

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

3.1 事件分发器工作原理

        在Qt中,我们发生的事件就是传递给了QObject对象,更具体点是传递给了QObject对象的event函数。所有的事件都会进入到这个函数里面,所以我们处理事件就要重写该函数。event函数本身不会处理事件,而是根据事件类型(type值)调用不同的事件处理函数。事件分发器就是工作在应用程序向下分发事件的过程:

        在事件分发的过程中,事件分发器也可以做拦截操作。通过bool event(QEvent *e)函数,其返回值为true表示拦截,不向下分发。

4. 事件过滤器

        在 Qt 中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。

        通过重写bool event(QEvent *e)函数利用事件分发器的原理,可以实现事件拦截,但是如果组件很多就需要重写很多event函数,非常麻烦,并且很可能导致其他问题。

Qt提供了外⼀种机制来达到这⼀⽬的:事件过滤器。 事件过滤器是在应⽤程序分发到 event事件分发器 之前,再做⼀次更⾼级的拦截。如下图⽰:

 

4.1 事件过滤器使用

(1)安装事件过滤器

安装接口:void installEventFilter(QObject *filterObj);

        控件调用installEventFilter安装事件过滤器后,发送给该控件的所有事件会先发送给它安装的过滤器filterObj,由filterObj中的eventfilter接口处理,如果eventfilter返回true,则事件被过滤,不会再发送给该控件。

(2)重写事件过滤器函数:eventfilter()

virtual bool eventfilter(QObject *watched, QEvent *event);

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

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

相关文章

云平台搭建

物联网云平台的基本概述 基本概念 随着物联网技术的快速发展,越来越多的设备需要接入网络以实现智能化功能,物联网平台应运而生。 物联网云平台(IoT Cloud Platform)是物联网生态系统中的核心组件,它通过提供一系列…

数学实验(Matlab语言环境和线性代数实验)

一、Matlab语言环境和线性代数实验 1.Matlab语言环境 Matlab简介 Matlab:Matrix Laboratry 矩阵实验室 Matlab 提供了强大的科学计算、灵活的程序设计流程、高质量的图形可视化与界面设计等功能,被广泛应用于科学计算、控制系统、信息处理等领域的分…

Elasticsearch 中的索引模板:如何使用可组合模板

作者:来自 Elastic Kofi Bartlett 探索可组合模板以及如何创建它们。 更多阅读: Elasticsearch:可组合的 Index templates - 7.8 版本之后 想获得 Elastic 认证吗?查看下一期 Elasticsearch Engineer 培训的时间! El…

【LeetCode 42】接雨水(单调栈、DP、双指针)

题面: 思路: 能接雨水的点,必然是比两边都低(小)的点。有两种思路,一种是直接计算每个点的最大贡献(也就是每个点在纵向上最多能接多少水),另一种就是计算每个点在横向上…

【JS逆向基础】前端基础-HTML与CSS

1,flask框架 以下是一个使用flask框架写成的serve程序 # noinspection PyUnresolvedReferences #Flash框架的基本内容from flask import Flask app Flask(__name__)app.route(/index) def index():return "hello index"app.route(/login) def login():re…

手机网页提示ip被拉黑名单什么意思?怎么办

‌当您使用手机浏览网页时,突然看到“您的IP地址已被列入黑名单”的提示,是否感到困惑和不安?这种情况在现代网络生活中并不罕见,但确实会给用户带来诸多不便。本文将详细解释IP被拉黑的含义、常见原因,并提供一系列实…

CCF编程能力等级认证 一级 第一次课

介绍 CCF 编程能力等级认证(GESP)为青少年计算机和编程学习者提供学业能力验证的规则和平台,由中国计算机学会发起并主办。 每年考试分四次,时间是每年的3月、6月、9月、12月,以当年每期公布的时间为准。 GESP适用年…

SpringBoot 讯飞星火AI WebFlux流式接口返回 异步返回 对接AI大模型 人工智能接口返回

介绍 用于构建基于 WebFlux 的响应式 Web 应用程序。集成了 Spring WebFlux 模块,支持响应式编程模型,构建非阻塞、异步的 Web 应用。WebFlux 使用了非阻塞的异步模型,能够更好地处理高并发请求。适合需要实时数据推送的应用场景。 WebClie…

Python爬虫中time.sleep()与动态加载的配合使用

一、动态加载网页的挑战 动态加载网页是指网页的内容并非一次性加载完成,而是通过JavaScript等技术在用户交互或页面加载过程中逐步加载。这种设计虽然提升了用户体验,但对于爬虫来说,却增加了抓取的难度。传统的爬虫方法,如简单…

AtCoder Beginner Contest 404 A-E 题解

还是ABC好打~比ARC好打多了&#xff08; 题解部分 A - Not Found 给定你一个长度最大25的字符串&#xff0c;任意输出一个未出现过的小写字母 签到题&#xff0c;map或者数组下标查询一下就好 #include<bits/stdc.h>using namespace std;#define int long long #def…

【mysql】常用命令

一 系统mysql用户密码查询 1、在工程目录如/usr/local/httpd/下的*.php中查找类似有db.inf的文件 以php为例。 2、在代码文件中确认有数据库连接的的功能实现 例如&#xff1a; $dbconf parse_ini_file(/usr/local/httpd/conf/db.inf); $link mysql_connect($dbconf[d…

macOS Arduino IDE离线安装ESP8266支持包

其实吧&#xff0c;本来用platformio也是可以的&#xff0c;不过有时候用Arduino IDE可能更快一些&#xff0c;因为以前一直是Arduino.app和Arduino IDE.app共存了一段时间&#xff0c;后来下决心删掉Arduino.app并升级到最新的Arduino IDE.app。删除了旧的支持板级支持包之后就…

网络靶场基础知识

一、网络靶场的核心概念 网络靶场&#xff08;Cyber Range&#xff09;是一种基于虚拟化和仿真技术的网络安全训练与测试平台&#xff0c;通过模拟真实网络环境和业务场景&#xff0c;为攻防演练、漏洞验证、安全测试和人才培养提供安全可控的实验空间。其核心目标是通过“虚实…

Python项目源码57:数据格式转换工具1.0(csv+json+excel+sqlite3)

1.智能路径处理&#xff1a;自动识别并修正文件扩展名&#xff0c;根据转换类型自动建议目标路径&#xff0c;实时路径格式验证&#xff0c;自动补全缺失的文件扩展名。 2.增强型预览功能&#xff1a;使用pandastable库实现表格预览&#xff0c;第三方模块自己安装一下&#x…

雷赛伺服电机

ACM0经济 编码器17位&#xff1a; ACM1基本 编码器23位磁编&#xff0c; ACM2通用 编码器24位光电&#xff0c; 插头定义&#xff1a;

【deepseek教学应用】001:deepseek如何撰写教案并自动实现word排版

本文讲述利用deepseek如何撰写教案并自动实现word高效完美排版。 文章目录 一、访问deepseek官网二、输入教案关键词三、格式转换四、word进一步排版 一、访问deepseek官网 官网&#xff1a;https://www.deepseek.com/ 进入主页后&#xff0c;点击【开始对话】&#xff0c;如…

CH32V208GBU6沁恒绑定配对获取静态地址

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

RT Thread Studio创建软件和硬件RTC工程

MCU型号&#xff1a;STM32F103RET6 一.配置软件模拟RTC 1.生成一个带串口输出的工程文件&#xff0c;新建RT-Thread项目工程文件。 2.查看电路图中的串口输出管脚&#xff0c;根据STMCubeMx软件可知此串口为USART1&#xff0c;选择芯片型号为STM32F103RET6&#xff0c;控制台…

苍穹外卖心得体会

1 登录认证 技术点&#xff1a;JWT令牌技术&#xff08;JSON Web Token&#xff09; JWT&#xff08;JSON Web Token&#xff09;是一种令牌技术&#xff0c;主要由三部分组成&#xff1a;Header头部、Payload载荷和Signature签名。Header头部存储令牌的类型&#xff08;如JW…

Zcanpro搭配USBCANFD-200U在新能源汽车研发测试中的应用指南(周立功/致远电子)

——国产工具链的崛起与智能汽车测试新范式 引言&#xff1a;新能源汽车测试的国产化突围 随着新能源汽车智能化、网联化程度的提升&#xff0c;研发测试面临三大核心挑战&#xff1a;多协议融合&#xff08;CAN FD/LIN/以太网&#xff09;、高实时性数据交互需求、复杂工况下…