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 QTimelabel槽函数中有一个方法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