【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.6 定时器事件
本章要实现的整体效果如下:

QT 中使用定时器,有两种方式:
- 定时器类:
QTimer - 定时器事件:
QEvent::Timer,对应的子类是QTimerEvent
本节通过一个案例,同时讲解这两种方式
案例:当点击 “开始” 按钮,两个标签同时向右移动,下边标签的定时间隔是上边标签的 2 倍,因此移动慢。当两个标签移动到最右侧时,回到最右端循环移动,整体效果,如下:
1. 定时器事件 QTimerEvent
1.1 界面布局
把两个标签以及 “启动”、“停止”、“复位” 三个按钮布局在界面上。
首先,来到 timer_widget.h,声明两个标签:
#include <QLabel>class TimerWidget : public QWidget
{
private:QLabel* lbl1;QLabel* lbl2;
};
然后,来到 timer_widget.cpp ,添加两个标签:
#include <QPushButton>TimerWidget::TimerWidget(QWidget* parent) : QWidget{parent}
{QVBoxLayout* verticalLayout = new QVBoxLayout(this);verticalLayout->setSpacing(0);verticalLayout->setContentsMargins(0, 0, 0, 0);// 1. 添加第一个QLabellbl1 = new QLabel(this);lbl1->setText("");lbl1->setFrameShape(QFrame::Box);lbl1->setFixedSize(100, 100);lbl1->setStyleSheet("background-color: red;");verticalLayout->addWidget(lbl1);// 2. 添加第二个QLabellbl2 = new QLabel(this);lbl2->setText("");lbl2->setFrameShape(QFrame::Box);lbl2->setFixedSize(100, 100);lbl2->setStyleSheet("background-color: blue;");verticalLayout->addWidget(lbl2);// 3. 添加按钮的水平布局QHBoxLayout* horizontalLayout = new QHBoxLayout(this);horizontalLayout->setSpacing(0);horizontalLayout->setContentsMargins(0, 0, 0, 0);QPushButton* btnStart = new QPushButton(this);btnStart->setText("开始");horizontalLayout->addWidget(btnStart);QPushButton* btnStop = new QPushButton(this);btnStop->setText("停止");horizontalLayout->addWidget(btnStop);QPushButton* btnReset = new QPushButton(this);btnReset->setText("复位");horizontalLayout->addWidget(btnReset);verticalLayout->addLayout(horizontalLayout);this->setStyleSheet(R"(QPushButton {font-size: 22px;})");
}
此时运行程序,效果如下:

1.2 关联信号槽
首先,来到 timer_widget.h,声明 3 个槽函数
class TimerWidget : public QWidget
{
private slots:void onStartClicked();void onStopClicked();void onResetClicked();
};
然后,来到 timer_widget.cpp,做一个空实现:
void TimerWidget::onStartClicked()
{
}void TimerWidget::onStopClicked()
{
}void TimerWidget::onResetClicked()
{
}
最后,来到 timer_widget.cpp,在构造中连接信号槽:
TimerWidget::TimerWidget(QWidget* parent) : QWidget{parent}
{// ...connect(btnStart, &QPushButton::clicked, this, &TimerWidget::onStartClicked);connect(btnStop, &QPushButton::clicked, this, &TimerWidget::onStopClicked);connect(btnReset, &QPushButton::clicked, this, &TimerWidget::onResetClicked);
}
1.3 重写 timerEvent
当定时时间到,就会自动调用 timerEvent() 函数。
首先,来到 timer_widget.h 中,声明 timerEvent() 函数,并声明两个定时器 id:
class TimerWidget : public QWidget
{
protected:void timerEvent(QTimerEvent* event);private:int id1;int id2;
};
然后,来到 timer_widget.cpp 中,实现 timerEvent() 函数:
void TimerWidget::timerEvent(QTimerEvent* event)
{// qDebug() << "timerEvent";if ( event->timerId() == id1 ) {lbl1->move(lbl1->x() + 5, lbl1->y());if ( lbl1->x() >= this->width() ) {lbl1->move(0, lbl1->y());}} else if ( event->timerId() == id2 ) {lbl2->move(lbl2->x() + 5, lbl2->y());if ( lbl2->x() >= this->width() ) {lbl2->move(0, lbl2->y());}}
}
说明:
- 在
timerEvent()函数中,向右移动标签。当标签超出当前窗口,重新回到最左侧 - 可以启动多个定时器,在
timerEvent()中,使用QTimerEvent类的timerId()函数可以获取哪个定时器定时时间到
1.4 实现槽函数,启动定时器
上一步中提到,定时时间到时,移动标签,那么就需要先启动定时器,并指定一个定时间隔。
首先,在 “启动” 按钮的槽函数中,启动定时器:
void TimerEventWidget::onStartClicked()
{id1 = startTimer(10); // 时间间隔10msid2 = startTimer(20); // 时间间隔20ms
}
然后,在 “停止” 按钮的槽函数中,停止定时器:
void TimerEventWidget::onStopClicked()
{killTimer(id1);killTimer(id2);
}
最后,在 “复位” 按钮的槽函数中,复位标签位置到最左侧:
void TimerEventWidget::onResetClicked()
{lbl1->move(0, lbl1->y());lbl2->move(0, lbl2->y());
}
此时运行,点击按钮,效果如下:

2. 定时器类 QTimer
接下来,使用定时器类 QTimer 来实现以上同样的效果
首先,在 timer_widget.h 声明两个定时器类的对象,以及定时超时的槽函数:
#include <QTimer>class TimerWidget : public QWidget
{
private slots:void onTimeout1();void onTimeout2();private:QTimer* timer1;QTimer* timer2;
};
然后,在 timer_widget.cpp 中实现两个定时超时槽函数:
void TimerWidget::onTimeout1()
{lbl1->move(lbl1->x() + 5, lbl1->y());if ( lbl1->x() >= this->width() ) {lbl1->move(0, lbl1->y());}
}void TimerWidget::onTimeout2()
{lbl2->move(lbl2->x() + 5, lbl2->y());if ( lbl2->x() >= this->width() ) {lbl2->move(0, lbl2->y());}
}
这里移动标签,并在标签超出当前窗口边界时,复位到最左侧
接着,修改 “启动”、“停止” 按钮的槽函数。
为便于切换定时器类和定时器事件这两种方式,定义了一个宏:
#define USE_TIMER_EVENTvoid TimerWidget::onStartClicked()
{
#ifdef USE_TIMER_EVENTid1 = startTimer(10);id2 = startTimer(20);
#elsetimer1->start(20);timer2->start(10);
#endif
}void TimerWidget::onStopClicked()
{
#ifdef USE_TIMER_EVENTkillTimer(id1);killTimer(id2);
#elsetimer1->stop();timer2->stop();
#endif
}
最后,在 timer_widget.cpp 的构造中创建定时器,并关联槽函数:
TimerWidget::TimerWidget(QWidget* parent) : QWidget{parent}
{// ...timer1 = new QTimer(this);connect(timer1, &QTimer::timeout, this, &TimerWidget::onTimeout1);timer2 = new QTimer(this);connect(timer2, &QTimer::timeout, this, &TimerWidget::onTimeout2);
}
此时,运行效果如下:

相关文章:
【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.6 定时器事件
本章要实现的整体效果如下: QT 中使用定时器,有两种方式: 定时器类:QTimer定时器事件:QEvent::Timer,对应的子类是 QTimerEvent 本节通过一个案例,同时讲解这两种方式 案例:当点击…...
阿里云服务器ECS实例规格族c/g/r等字母说明
阿里云服务器ECS实例命名规则:ecs.<规格族>.large字母含义命名说明,包括x86、ARM架构、GPU异构计算、弹性裸金属、超级计算集群SCC云服务器,c代表计算型、g代表通用型、r代表内存型、u代表通用算力型、e代表经济型e实例,阿里…...
Everything和SVN结合使用-在Everything中显示SVN
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...
代码随想录算法训练营第五十二天| 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV
今日学习的文章链接和视频链接 123.买卖股票的最佳时机III 视频讲解:https://www.bilibili.com/video/BV1WG411K7AR https://programmercarl.com/0123.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIII.html 188.买卖股票的…...
②. GPT错误:图片尺寸写入excel权限错误
꧂问题最初 ꧁ input输入图片路径 print图片尺寸 大小 长宽高 有颜色占比>0.001的按照大小排序将打印信息存储excel表格文件名 表格路径 图片大小 尺寸 颜色类型 占比信息input输入的是文件就处理文件 是文件夹📁就处理文件。路径下的图片 1. 是处理本路径图片 …...
JQuery、JSON、AJAX、XML、IO流、多线程、反射核心知识点详解
JQuery 一、什么是JQuery JQuery是JavaScript的一个框架,对js的封装,使得js简单易学 优点: 1、不用考虑浏览器兼容性问题 2、jquery拥有强大的选择器,简化了js代码 3、jquery提供了很多系统函数,直接调用 二、版本 1.x…...
基于python的多种图像增强算法实现
基于python的多种图像增强算法实现 引言工具算法增强对比度直方图均衡化锐化图像噪声消除中值滤波均值滤波高斯滤波双边滤波增强对比度直方图均衡化总结全部资源引用引言 本项目使用python实现多种空域增强的图像增强算法,并使用了pyqt编写页面。通过点击不同页面的多种按钮,…...
Java前后端交互实现班级管理(查询)
1,数据库创建存储专业信息的表 2,后端: 连接数据库工具类DBUtil.java: package com.ffyc.webserver.util;import java.sql.*;public class DButils {static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch…...
论文速递 | 8月下旬9月上旬Operations ResearchManagement Science文章精选
编者按 本期我们选取了8月下旬及9月上旬Operations Research文章2篇,Management Science文章4篇期刊文章,着眼于各种不同场景下对于风险的预测、量化及管理,通过聚焦于风险这一主题,体系化地形成文章精选。 文章1 Computation of…...
DataBinding使用报错
val dataBinding DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)报错一: Unresolved reference: ActivityMainBinding 首先你要知道一个概念,ActivityMainBinding是DataBinding中的一种视频绑定ÿ…...
08Maven中的继承和聚合的作用
Maven中的继承 实际开发中对一个比较大型的项目进行了模块拆分 , 一个project下面创建了很多个modul, 每一个module都需要配置自己的依赖信息 开发中使用的同一个框架内的不同jar包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一 传统方…...
Ansible运行临时命令及常用模块介绍
目录 一.运行临时命令 1.基本语法格式 2.查看当前版本已安装的所有模块 二.ansible常见模块 1.command模块 2.shell模块 3.raw模块 4.script模块 5.file模块 参数列表: 示例: 6.copy模块 参数列表: 示例: 7.fetch模…...
EtherCAT报文-APRD(自动增量读)抓包分析
0.工具准备 1.EtherCAT主站 2.EtherCAT从站(本文使用步进电机驱动器) 3.Wireshark1.EtherCAT报文帧结构 EtherCAT使用标准的IEEE802.3 Ethernet帧结构,帧类型为0x88A4。EtherCAT数据包括2个字节的数据头和44-1498字节的数据。数据区由一个或…...
论文阅读:Seeing in Extra Darkness Using a Deep-Red Flash
论文阅读:Seeing in Extra Darkness Using a Deep-Red Flash 今天介绍的这篇文章是 2021 年 ICCV 的一篇 oral 文章,主要是为了解决极暗光下的成像问题,通过一个深红的闪光灯补光。实现了暗光下很好的成像效果,整篇文章基本没有任…...
将license验证加入到系统中
1.将ClientDemo下的cn文件夹的内容导入项目对应的java目录下。 2.将license-config.properties文件导入resources目录下。 3.在项目的pom.xml中添加如下依赖。 <properties><!-- Apache HttpClient --><httpclient>4.5.5</httpclient><!-- License…...
中断机制-interrupt和isInterrupted源码分析、中断协商案例
当前线程的中断标识为true,是不是线程就立刻停止? 答案是不立刻停止,具体来说,当对一个线程,调用interrupt时: 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,仅此…...
我与COSCon的故事【时光的故事】
曾经 2019年的时候,我还在日本读研究生,做一些物联网 (Internet of Things, IoT) 网络中的底层P2P (Peer to Peer) 通讯仿真模拟。这个方向是新来的Nguyen老师的新方向,它跟计算机强相关,但是很小众,实验室里也没有前辈…...
【科学文献计量】利用pybibx分析Scopus文献数据集(EDA,N-Grams,Cluster,Network analysis,NLP)
利用pybibx分析Scopus文献数据集 1 运行前准备1.1 数据集1.2 前置库2 加载库3 数据导入4 探索式数据分析,即EDA4.1 表格可视化4.2 词云图可视化4.3 N-Grams可视化4.4 文献聚类4.5 主题词演化4.6 桑基图可视化4.7 树图可视化4.8 作者生产力可视化5 网络可视化5.1 文献引用与被引…...
-带你看懂11种API类型及应用-
一起走进多样的API,多样的精彩 随着互联网行业的日益发展,API(Application Programming Interface)这个名词对于绝大多数来说都已不再陌生。然而,实际上,根据不同标准可以划分出不同类型的API。今天,让我们来走…...
集成友盟qq互联分享,导出风险问题处理
处理方案:移除 android:exported"true"即可。 注意友盟SDK QQ share 里默认配置是android:exported"true",所以要覆盖即可。...
XZ1851输入电压6-40V 输出电流2.5A 输出电压ADJ(小于39V)
产品概述 XZ1851 是一款内置功率 MOSFET的单片降压型开关模式转换器。 XZ1851在 6-40V 宽输入电源范围内实现2.5 A最大输出电流,并且具有出色的线电压和负载调整率。 XZ1851 采用 PWM 电流模工作模式,环路易于稳定并提供快速的瞬态响应。 XZ1851 外部提供…...
DeerFlow资源优化实践:控制Python执行环境内存占用方法
DeerFlow资源优化实践:控制Python执行环境内存占用方法 1. 认识DeerFlow:您的智能研究助手 DeerFlow是一个基于LangStack技术框架开发的深度研究开源项目,它就像是您的个人研究团队,能够帮您完成各种复杂的调研任务。这个工具整…...
Linux服务器卡死?5分钟定位hung task与soft lockup的实战技巧
Linux服务器卡死?5分钟定位hung task与soft lockup的实战技巧 凌晨三点,服务器监控突然告警——核心业务节点失去响应。作为运维工程师,这种场景往往意味着不眠之夜。但不同于新手的手足无措,经验丰富的系统管理员知道:…...
RuView:无摄像头环境下人体姿态追踪的创新方法探索
RuView:无摄像头环境下人体姿态追踪的创新方法探索 【免费下载链接】RuView Production-ready implementation of InvisPose - a revolutionary WiFi-based dense human pose estimation system that enables real-time full-body tracking through walls using com…...
文本驱动图表工具:重新定义可视化创作的效率革命
文本驱动图表工具:重新定义可视化创作的效率革命 【免费下载链接】mermaid mermaid-js/mermaid: 是一个用于生成图表和流程图的 Markdown 渲染器,支持多种图表类型和丰富的样式。适合对 Markdown、图表和流程图以及想要使用 Markdown 绘制图表和流程图的…...
CosyVoice CPU部署实战:如何优化AI语音模型的推理速度
最近在做一个智能客服项目,需要把语音合成模型部署到一些只有CPU的服务器上。一开始直接用PyTorch加载CosyVoice模型,那个推理速度真是让人着急,生成一句话要等好几秒,完全没法满足实时交互的需求。这让我下定决心,必须…...
OpenClaw备份方案:Qwen3.5-9B模型接口故障时的降级策略
OpenClaw备份方案:Qwen3.5-9B模型接口故障时的降级策略 1. 为什么需要备份方案? 上周我正用OpenClaw处理一批重要文件归档任务时,突然遇到Qwen3.5-9B接口响应超时。当时正在半夜,没有备用方案的我只能眼睁睁看着自动化流程中断&…...
OpenClaw安全风险全解析:从架构漏洞到应对实践
OpenClaw安全风险全解析:从架构漏洞到应对实践 2026年初,一款名为OpenClaw(俗称“龙虾”)的开源AI智能体风靡全球,上线数月即斩获超20万GitHub星标,成为史上增长最快的开源项目之一。然而,随着大量用户将这一“可真正执行任务的AI”部署于个人电脑和生产环境,一系列触目…...
Pixel Fashion Atelier应用场景:数字藏品创作者批量生成稀缺性像素时装NFT
Pixel Fashion Atelier应用场景:数字藏品创作者批量生成稀缺性像素时装NFT 1. 像素时装NFT创作新范式 在数字藏品领域,稀缺性和独特性是核心价值。Pixel Fashion Atelier为创作者提供了一个革命性的解决方案,将AI生成技术与像素艺术美学相结…...
4吨卧式燃气蒸汽锅炉食品厂洗涤商用
WNS型4吨卧式燃气蒸汽锅炉,专为食品加工、商用洗涤等行业量身打造,是高效稳定、环保节能的核心供汽设备,完美适配食品蒸煮杀菌、洗涤熨烫烘干等高频蒸汽需求,助力企业降本增效、合规生产。 锅炉采用卧式三回程湿背式经典结构&…...
