Qt 之 QTimer

article/2025/9/13 16:16:06

作者: 一去、二三里
个人微信号: iwaleon
微信公众号: 高效程序员

QTimer类提供了重复和单次触发信号的定时器。

QTimer类为定时器提供了一个高级别的编程接口。很容易使用:首先,创建一个QTimer,连接timeout()信号到适当的槽函数,并调用start(),然后在恒定的时间间隔会发射timeout()信号。

注意:当QTimer的父对象被销毁时,它也会被自动销毁。

详细说明

在Qt之模拟时钟中,1秒(1000毫秒)更新一次:

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);

start()之后,每秒都会调用update()。

可以通过设置setSingleShot(true)来让定时器只执行一次。也可以使用静态函数QTimer::singleShot():

QTimer::singleShot(200, this, SLOT(updateCaption()));

在多线程程序中,可以在一个有事件循环的任何线程中使用QTimer。使用QThread::exec(),从非GUI线程启动一个事件循环。 Qt使用定时器的线程关联,以确定哪个线程会发出timeout()信号。正因为如此,你必须在它的线程中启动和停止定时器,不可能从另一个线程启动定时器。

作为一个特例,一旦窗口系统事件队列中的所有事件都已经被处理完,一个定时为0的QTimer就会到时间了。当需要提供流畅的用户界面时,可以用这来做比较繁重的工作。

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(processOneThing()));
timer->start();

这时,processOneThing()将会被重复调用并且应该很快返回(通常在处理一个数据项之后),这样Qt可以把事件传送给窗口部件,并且一旦它完成这个工作就停止这个定时器。这是在图形用户界面应用程序中实现繁重的工作的一个典型方法,现在多线程可以在越来越多的平台上使用,我们希望0-毫秒QTimer对象最终被线程替代。

精度

定时器的精度取决于底层操作系统和硬件。绝大多数平台支持精度为1毫秒,尽管定时器的准确性在许多现实世界的情况下和这不相符。

准确性也取决于定时器类型(Qt::TimerType)。对于Qt::PreciseTimer来说,QTimer将试图保持精确度在1毫秒。精确的定时器也从来不会比预计的还要早超时。

对于Qt::CoarseTimer和Qt::VeryCoarseTimer类型,QTimer可能早于预期,在间隔之内被唤醒:Qt::CoarseTimer为间隔的5%,Qt::VeryCoarseTimer为500毫秒。

枚举Qt::TimerType:

常量描述
Qt::PreciseTimer0精确的定时器,尽量保持毫秒精度。
Qt::CoarseTimer1粗略的定时器,尽量保持精度在所需的时间间隔5%范围内。
Qt::VeryCoarseTimer2很粗略的定时器,只保留完整的第二精度。

在UNIX (包括: Linux、OS X、iOS)中,Qt将为Qt::PreciseTimer保持毫秒精度,对于Qt::CoarseTimer,间隔将调整到5%,使定时器与其他定时器匹配或在差不多在同一时间,目标是让大多数定时器在同一时间醒来,从而减少CPU唤醒和功耗。

在Windows上,Qt将为Qt::PreciseTimer使用Windows的多媒体定时器工具(如果可用),为Qt::CoarseTimer和Qt::VeryCoarseTimer使用正常的Windows定时器。

所有平台上,Qt::VeryCoarseTimer的间隔被四舍五入到最接近完整的第二位(例如:23500ms的时间间隔将被舍入到24000ms,20300ms舍入至20000)。

替代QTimer

另一个使用QTimer的方法:为你的对象调用QObject::startTimer(),在你的类中(必须继承QObject)重新实现QObject::timerEvent()事件处理器。缺点是timerEvent()不支持像单次触发定时器或信号那样的高级特性。

另一个选择是QBasicTimer。它通常比使用QObject::startTimer() 直接。可以查看助手中Timers描述的三种方法。

一些操作系统限制可能会限制定时器的数量,Qt会尽力在限制范围内工作。

可参考:QBasicTimer、QTimerEvent、QObject::timerEvent()、Timers、Analog Clock Example、Wiggly Example。

成员函数

  • bool isActive() const
    如果定时器正在运行,返回true,否则返回false。

  • int remainingTime() const
    返回定时器的剩余时间(毫秒为单位),直到超时。

如果定时器不活跃,返回值是-1。如果定时器过期,返回值为0。

  • void setInterval(int msec)
    设置超时间隔(毫秒为单位)。

默认值是0,这时,一旦窗口系统事件队列中的所有事件都已经被处理完,一个时间间隔为0的QTimer就会触发。

  • void setSingleShot(bool singleShot)
    设置定时器是否为单次触发。

单次触发定时器只触发一次,非单次的话,则每过一个时间间隔都会触发。

  • void setTimerType(Qt::TimerType atype)
    设置定时器的准确性。默认值是Qt::CoarseTimer。

  • int timerId() const
    如果定时器正在运行,返回定时器的ID,否则返回-1。

  • void start(int msec)
    启动或重新启动一个超时时间间隔为毫秒的定时器。

如果定时器正在运行,它将被停止和重新启动。如果singleShot为true,定时器将只激活一次。

  • void start()
    同上,重载了start()。

  • void stop()
    停止定时器。

信号

  • void timeout()
    定时器超时后,这个信号被发射。

注意:这是一个私有的信号。它可以在信号连接使用,但不能由用户发出。

示例

下面,我们以QTimer为例,利用开始和停止按钮来操作一个进度条的更新。

效果

这里写图片描述

源码

QPushButton *pStartButton = new QPushButton(this);
QPushButton *pStopButton = new QPushButton(this);
m_pProgressBar = new QProgressBar(this);
m_pTimer = new QTimer();pStartButton->setText(QString::fromLocal8Bit("开始"));
pStopButton->setText(QString::fromLocal8Bit("停止"));m_pProgressBar->setRange(0, 100);
m_pProgressBar->setValue(50);// 设置超时间隔
m_pTimer->setInterval(1000);// 连接信号槽
connect(pStartButton, SIGNAL(clicked(bool)), m_pTimer, SLOT(start()));
connect(pStopButton, SIGNAL(clicked(bool)), m_pTimer, SLOT(stop()));
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(updateProgress()));// 槽函数
void MainWindow::updateProgress()
{// 获取当前进度值,+1int nCurrentValue = m_pProgressBar->value();nCurrentValue++;if (nCurrentValue >= 100)m_pTimer->stop();// 设置新的进度值m_pProgressBar->setValue(nCurrentValue);
}

在槽函数updateProgress()中,首先通过m_pProgressBar->value()来获取当前进度值,然后加1,当进度大于等于100时停止定时器(再继续执行已经没任何意义了,因为进度已经达到了100,而且不停止还消耗资源),然后设置进度条的值。

更多参考

  • Qt之模拟时钟

http://chatgpt.dhexx.cn/article/8HF1AQfO.shtml

相关文章

DEV、SIT、UAT、PET、SIM、PRD、PROD缩写介绍

按开发、测试、上线的时间线排序: DEV Development 研发环境 SIT System Integrate Test 系统集成测试环境(内测) UAT User Acceptance Test 用户验收测试环境 PET Performance Evaluation Test 性能评估测试环境(压测&#xff0…

什么是SIT, UAT测试

2019独角兽企业重金招聘Python工程师标准>>> SIT测试 SIT(System Integration Testing)系统集成测试,也叫做集成测试,是软件测试的一个术语,在其中单独的软件模块被合并和作为一个组测试。它在单元测试以后和在系统测试之前。集成…

UAT测试和SIT测试的区别

区别如下: 1、UAT:终端用户集成测试,主要是要求用户参与进测试流程,并得到用户对软件的认可,鼓励用户自己进行测试设计和进行破坏性测试,充分暴露系统的设计和功能问题,显然,用户的认可和破坏性…

UT-FT-ST测试

单元测试(UT)、功能测试(FT): 目的:1、尽量避免写的代码测试人员频繁的来找你其他地方又出问题了;2、提供的接口不可用;3、一个bug修复了引入了其他的bug或者其他用例变红了; 理解:在实现函数功能的时候编…

unittest教程__测试报告(6)

用例执行完成后,执行结果默认是输出在屏幕上,其实我们可以把结果输出到一个文件中,形成测试报告。 unittest自带的测试报告是文本形式的,如下代码: import unittestif __name__ __main__:# 识别指定目录下所有以tes…

Pytest 分组测试

有时候需要针对不同的测试环境跑不同的测试用例,如:冒烟测试、sit、uat、prd,所以给自动化测试用例做标记分组是很有必要的,pytest.mark 可以轻松实现这个功能。首先需要注册自定义标记。 通过使用pytest.mark帮助程序&#xff0…

冒烟测试回归测试UATSIT

在软件研发中,冒烟测试其实是微软首先提出来的一个概念,和微软一直提倡的每日build(构建版本)有很密切的联系。具体说,冒烟测试就是在每日build(构建版本)建立后,对系统的基本功能进…

使用GIT提交代码流程

安装步骤:双击Git-2.27.0-64-bit.exe安装 双击TortoiseGit-2.10.0.2-64bit.msi安装 代码提交一般有五个步骤: 1.查看目前代码的修改状态 2.查看代码修改内容 3.暂存需要提交的文件 4.提交已暂存的文件 5.同步到服务器 登陆复制仓库的地址然后复制到下图的Directory…

Git提交代码的流程

企业级项目git远程仓库一般是由master/test/dev三个分支构成,开发人员是在dev上做开发,当需要发布测试环境或者生产环境时管理员会把开发人员提交的代码合并到test或者master上。 开发人员git操作步骤: 1.git clone 把远程dev上的代码克隆到本…

傻瓜式Git提交代码流程【写给初学者】

前言 Git是程序员工作中最最常用的分布式版本控制系统,为的就是解决那种多人协作、多次修改的问题,虽说Git可以应用于各行各业,但是实际上还是程序员用的最多了,应该说是程序员的必备技能之一了,如果你还不会Git&…

vs2019中git提交代码的步骤

目录 前言 一、在vs2019的git界面提交代码 二、使用git命令行提交代码 总结 前言 在vs2019中使用git提交代码的步骤和一些常见问题。 一、在vs2019的git界面提交代码 1.切换到需要提交代码的分支上,首先更新分支。 vs2019工具栏选择Git,点击更新。 2.…

IDEA使用git提交代码

1.将鼠标移动到需要提交的代码文件上;2.右键文件夹,找到Git选项;3.进入选项中的Repository;4.然后点击push就可以将暂存的代码提交到 Git 服务器上。

在Idea用Git提交代码

前提是安装了Git 1、右键选择如下: 2、选择提交前文件、描述提交信息、提交到本地仓库,操作如下: 3、确定是否提交 4、推送远程仓库,右键选择如下:

idea上git提交代码的正确步骤

IDEA中项目集成git提交代码详细步骤 一:pull代码 在提交代码之前,我们必须先对代码就行更新操作,这一步非常重要,如果不进行更新代码操作,当有其他小伙伴有更改的内容已经提交到代码仓库但是我们本地缺没有更新的话&…

idea中使用git提交代码步骤

目录 一、先更新代码二、更新代码后的2种情况三、代码添加到本地仓库四、代码提交到缓冲区五、代码提交到远程git仓库 lz部分截图参考此链接https://blog.csdn.net/u013452337/article/details/79956604 一、先更新代码 1、在提交项目之前必须先对项目进行更新(一定…

Git命令提交代码步骤

1.初始化:创建一个git仓库,创建之后就会在当前目录生成一个.git的文件 git init2.添加文件:把文件添加到缓冲区 git add filename3.添加所有文件到缓冲区(从目前掌握的水平看,和后面加“.”的区别在于,加…

idea git提交代码

0、新工程如何加入git管理 复制.gitignore文件进工程根目录 .gitignore文件内容为: HELP.md target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/### STS ### .apt_generated .classpath .factorypath .project .settings…

Git 提交代码步骤总结

第一步:拉取远程代码,更新本地代码,避免覆盖其他人的代码 指令:git pull (拉取远程master分支的代码) 截图: 指令: git pull origin cas (拉取远程cas分支的代码) 截图: 第二步:查看当前项目…

Git 提交代码步骤

第一步: 提交代码第一步:git status 查看当前状态 当你忘记修改了哪些文件的时候可以使用 git status 来查看当前状态, 红色的字体显示的就是你修改的文件。 第二步: 提交代码第二步:git add . 或者 git add xxx 如图1、如…

git提交代码的两种方法步骤

文章目录 一、Git Bash提交方式1.首次提交,先输入github/gitlab等的用户名和邮箱2.将路径改为需要提交的项目路径3.查看上次提交之后的是否有修改文件4.将修改文件存入暂存区5.提交修改文件6.拉取远程与本地合并7.推送本地到远程合并 二、VScode提交方式1.将文件存入…