当前位置: 首页 > news >正文

1.4 Qt定时器类QTimer

1. 定时器QTimer

在进行窗口程序的处理过程中, 经常要周期性的执行某些操作, 或者制作一些动画效果,看似比较复杂的问题使用定时器就可以完美的解决这些问题, Qt中提供了两种定时器方式,一种是使用Qt中的事件处理函数这个在后续章节会给大家做细致的讲解,本节主要给大家介绍一下Qt中的定时器类QTimer的使用方法。

要使用它,只需创建一个QTimer类对象,然后调用其start()函数开启定时器,此后QTimer对象就会周期性的发出timeout()信号。我们先来了解一下这个类的相关API。

1.1 public/slot function

// 构造函数 // 如果指定了父对象, 创建的堆内存可以自动析构 QTimer::QTimer(QObject *parent = nullptr); // 设置定时器时间间隔为 msec 毫秒 // 默认值是0,一旦窗口系统事件队列中的所有事件都已经被处理完,一个时间间隔为0的QTimer就会触发 void QTimer::setInterval(int msec); // 获取定时器的时间间隔, 返回值单位: 毫秒 int QTimer::interval() const; // 根据指定的时间间隔启动或者重启定时器, 需要调用 setInterval() 设置时间间隔 [slot] void QTimer::start(); // 启动或重新启动定时器,超时间隔为msec毫秒。 [slot] void QTimer::start(int msec); // 停止定时器。 [slot] void QTimer::stop(); // 设置定时器精度 /* 参数: - Qt::PreciseTimer -> 精确的精度, 毫秒级 - Qt::CoarseTimer -> 粗糙的精度, 和1毫秒的误差在5%的范围内, 默认精度 - Qt::VeryCoarseTimer -> 非常粗糙的精度, 精度在1秒左右 */ void QTimer::setTimerType(Qt::TimerType atype); Qt::TimerType QTimer::timerType() const; // 获取当前定时器的精度 // 如果定时器正在运行,返回true; 否则返回false。 bool QTimer::isActive() const; // 判断定时器是否只触发一次 bool QTimer::isSingleShot() const; // 设置定时器是否只触发一次, 参数为true定时器只触发一次, 为false定时器重复触发, 默认为false void QTimer::setSingleShot(bool singleShot);

1.2 signals

这个类的信号只有一个, 当定时器超时时,该信号就会被发射出来。给这个信号通过conect()关联一个槽函数, 就可以在槽函数中处理超时事件了。

// 当定时器超时时,该信号就会发出。 [signal] void QTimer::timeout();

1.3 static public function

// 其他同名重载函数可以自己查阅帮助文档 /* 功能: 在msec毫秒后发射一次信号, 并且只发射一次 参数: - msec: 在msec毫秒后发射信号 - receiver: 接收信号的对象地址 - method: 槽函数地址 */ [static] void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method);

1.4. 定时器使用举例

周期性定时器

// 创建定时器对象 QTimer* timer = new QTimer(this); // 修改定时器对象的精度 timer->setTimerType(Qt::PreciseTimer); // 按钮 loopBtn 的点击事件 // 点击按钮启动或者关闭定时器, 定时器启动, 周期性得到当前时间 connect(ui->loopBtn, &QPushButton::clicked, this, [=]() { // 启动定时器 if(timer->isActive()) { timer->stop(); // 关闭定时器 ui->loopBtn->setText("开始"); } else { ui->loopBtn->setText("关闭"); timer->start(1000); // 1000ms == 1s } }); connect(timer, &QTimer::timeout, this, [=]() { QTime tm = QTime::currentTime(); // 格式化当前得到的系统时间 QString tmstr = tm.toString("hh:mm:ss.zzz"); // 设置要显示的时间 ui->curTime->setText(tmstr); });

一次性定时器

// 点击按钮 onceBtn 只发射一次信号 // 点击按钮一次, 发射一个信号, 得到某一个时间点的时间 connect(ui->onceBtn, &QPushButton::clicked, this, [=]() { // 获取2s以后的系统时间, 不创建定时器对象, 直接使用类的静态方法 QTimer::singleShot(2000, this, [=](){ QTime tm = QTime::currentTime(); // 格式化当前得到的系统时间 QString tmstr = tm.toString("hh:mm:ss.zzz"); // 设置要显示的时间 ui->onceTime->setText(tmstr); }); });

笔记

1.QTimer类的常用API介绍

构造函数只有一个父对象类型的指针,用于把这个节点挂到一棵对象树上,最终可以实现内存的自动回收

把父对象指针传进去后,子对象内部记录了这个父对象的地址(子找父),同时父对象把子对象的指针加入自己的子对象列表(父找子)。这样建立了双向关系:父对象销毁时能通过列表找到所有子对象并销毁它们,子对象也能通过 parent 指针找到父对象。

对象树运行原理

1.所有继承QObject的类都自带父子链表;

2.传入parent时,内部会执行:父对象把当前对象加入自己的子对象列表;

3.父对象析构时,递归销毁全部子对象;

4.典型场景:窗口上所有按钮、输入框、定时器都挂载窗口为父,窗口关闭一键全部回收内存。

首先通过构造函数创建QTimer对象,然后调用start方法去启动定时器,启动定时器必须设定一个时间间隔(定时周期),当定时周期到达之后,定时器就会发射一个timeout信号,然后就需要一个指定的槽函数来处理这个信号

设置定时器精度,获取定时器精度

判定当前定时器是否正在运行

默认情况下是发生多次,可以设置是否只发射一次

2.QTimer定时器类的使用举例

举例:获取系统时间,把系统时间显示到当前窗口中

新建一个基于窗口的应用程序

在ui界面放两个控件

loop 翻译:循环

新建一个Push Button改名为loopBtn

新建一个Label控件,改名为curTime

分析需求:点一下开始按钮,然后启动定时器,定时器进行周期性定时,当定时器出发一次timeout信号就通过槽函数把时间写到label控件中

操作:先进行信号槽连接处理按钮的点击事件,当窗口的按钮被按下去就会发出一个clicked信号,当前mainwindow窗口的实例对象捕捉到这个信号之后就会进行处理,通过匿名槽函数执行相应的动作。

首先设置定时器、启动定时器

设置定时器对象时把当前窗口对象作为父对象,当前mainwindow窗口被析构的时候定时器对象也会被释放。

设置定时器发射时间为1s,意味着1s之后一个timeout信号被发射出来,timeout信号发射后需要对这个信号进行处理,接着进行一个connect操作,当timeout信号发出后让当前对象this接收这个信号,然后通过匿名槽函数进行获取、显示当前系统时间的处理操作。

添加对应日期的头文件

#include <QTime>

label槽函数中有一个方法setText可以把获取到的字符串信息设置到当前对象中,也就是显示到窗口中。

点击按钮进行的操作

进行优化:假设按钮按下去之后,开始就变成关闭,不能说定时器已经启动还能再次启动。

先判定当前定时器是否在工作,如果正在工作,就关闭定时器并把定时器显示为开始,当点击开始按钮定时器启动后就需要把按钮显示的标题改为关闭。

代码

#include "mainwindow.h" #include "ui_mainwindow.h" #include <QTimer> #include <QTime> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // ============================================================ // ★ 创建定时器对象 // ============================================================ QTimer* timer = new QTimer(this); // parent = this → MainWindow 销毁时自动清理定时器 // ============================================================ // ★ 连接1:按钮点击 → 启动/停止定时器 // ============================================================ connect(ui->loopBtn, &QPushButton::clicked, this, [=](){ if(timer->isActive()) // 定时器运行中 → 停止 { timer->stop(); ui->loopBtn->setText("开始"); // 按钮提示"开始" } else // 定时器已停止 → 启动 { ui->loopBtn->setText("关闭"); // 按钮提示"关闭" timer->start(1000); // 每秒触发一次 timeout } }); // ============================================================ // ★ 连接2:定时器 timeout → 自动更新时间显示 // ============================================================ connect(timer, &QTimer::timeout, this, [=](){ QTime tm = QTime::currentTime(); // 获取当前时间 QString tmstr = tm.toString("hh:mm:ss.zzz"); // 格式化 ui->curTime->setText(tmstr); // 更新显示 }); } MainWindow::~MainWindow() { delete ui; }

点击按钮会以1秒的间隔显示当前系统时间

可以注意到时间每过1s,毫秒的误差在几毫秒的范围内,如果对定时器精度要求更高,可以修改当前计时器对象的精度

setTimerType()参数是一个Qt::TimerType类型的枚举,

Qt::PreciseTimer是最高精度,启动显示偏差基本不变或者在1ms内

如何使用QTimer这个类一次性定时

在ui界面选中控件,按住ctrl键拖动复制一份

将第二个开始按钮的名称改为onceBtn,对应的label name也该成onceTime

http://www.jsqmd.com/news/1388965/

相关文章:

  • 从零部署AI智能体:基于LangChain与本地大模型的Hermes Agent实战指南
  • FFmpeg实战中文语音自适应比特率编码:从原理到HLS/DASH流生成
  • 微信好友自动化添加工具:3分钟快速上手,效率提升90%
  • 磁盘空间不足怎么清理?不删系统文件,6步安全腾出C盘空间
  • GBase 8a数据加载操作纪实:从基础配置到性能调优的完整实践
  • 2026年8月重庆市潼南区移动1000M单宽带办理全流程避坑攻略 - 找卡家园
  • TARE项目集成MCP本地环境:从核心概念到实战配置指南
  • 从零部署Hermes Agent:实战AI智能体自动化终端与飞书集成
  • 802.1AS时间同步协议:从PTP原理到汽车TSN纳秒级同步实践
  • AI Agent开发:构建安全可控的智能体循环与护栏机制
  • 峰火智能一键紧急报警柱解决方案,打造公共区域快速响应安全防护体系
  • 黄埔区最值得信赖的装修公司大揭秘!
  • OpenCLI:将网页操作转化为命令行工具,实现自动化与脚本化
  • 2026年8月永州市联通2000M宽带办理避坑全攻略 - 找卡家园
  • 告别半年等待:低代码重构企业数字化开发范式
  • 从零构建AI智能体:基于Python与LLM的云端文件管理助手实践
  • HarmonyOS APP开发---“热榜“资讯聚合App,需要用到这个库
  • 微信小程序路由API全解析:从页面栈原理到实战避坑指南
  • 吃透WorkBuddy六大核心功能,办公效率直接翻倍
  • Agnes 2.5 Flash模型API集成实战:从接入测试到生产部署
  • ANSYS Fluent安装与配置全攻略:从系统检查到许可验证
  • 自智网络中多意图共漂移故障的预测与根因解耦技术解析
  • 从入门到精通:全面解析为何企业必须深度关注济南网站建设及其背后的深层逻辑
  • AI安全新挑战:概念注入攻击与模型认知完整性防御
  • 微软MAI-Image-2.6模型解析:小模型如何靠审美与指令遵循冲击文生图榜单
  • DeepL翻译插件终极指南:5分钟实现网页无障碍阅读
  • 2026年8月永州市联通1000M宽带办理申请全攻略与真实避坑经验 - 找卡家园
  • 找文件总是费时?盘点Windows文件搜索快捷键与进阶技巧
  • 基于MCP协议与优麦云构建广告自动化Skill:从概念到工程实践
  • 重庆思庄技术分享-oracle数据库修改db_name