参考原文链接:https://blog.csdn.net/weixin_43780415/article/details/131389737
Qt定时器类QTimer是一个用于重复执行或延迟执行函数的类。它可以在一定时间间隔内发送一个信号,也可以在指定的时间后发送一个信号。QTimer是一个基于事件的定时器,即它使用Qt的事件循环来触发定时器事件。
要使用它,只需创建一个QTimer类对象,然后调用其 start() 函数开启定时器,此后QTimer对象就会周期性的发出 timeout() 信号。我们先来了解一下这个类的相关API。
以下是QTimer常用的函数:
QTimer(int interval, QObject * parent = nullptr)//构造函数,创建一个新的QTimer对象,间隔时间由`interval`指定。`parent`参数可以设置QObject的父对象。
start(int msec = 0)// 启动or重新启动计时器。
stop()// 停止计时器。
setInterval(int interval)// 设置计时间隔。
setSingleShot(bool singleShot)// 设置计时器方式,若参数`singleShot`为`true`,则定时器只会在定时时间间隔到达时发出一次timeout()信号,否则定时器会一直重复发出timeout()信号。
timerId() const// 返回此计时器的标识符。
isActive() const// 返回计时器是否处于活动状态
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);
signals
这个类的信号只有一个, 当定时器超时时,该信号就会被发射出来。给这个信号通过conect()关联一个槽函数, 就可以在槽函数中处理超时事件了。
[signal] void QTimer::timeout();
static public function
/*
功能: 在msec毫秒后发射一次信号, 并且只发射一次
参数:- msec: 在msec毫秒后发射信号- receiver: 接收信号的对象地址- method: 槽函数地址
*/
[static] void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method);
示例(获取系统时间并且将其显示到窗口中):
创建名为QTimerTest的项目,在mainwindow.ui文件中创建两个按钮和两个label
上面的“开始计时”按钮点击之后,在TextLabel中显示动态时间,下面的“开始计时”按钮点击之后,只获取一次当前时间。
mainwindow.cpp代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTime>
#include <QTimer>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建定时器对象QTimer* timer = new QTimer(this);//修改定时器精度//timer->setTimerType(QTimer::PreciseTimer);//按钮的点击事件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);});//发射一次信号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);});});
}MainWindow::~MainWindow()
{delete ui;
}
运行结果:
示例主要代码(每间隔一秒向控制台发送一条消息):
//每间隔一秒向控制台发送一条信息
connect(timer, &QTimer::timeout, this, [=]() {
qDebug() << "This is the QTimer test!";
});
timer->start(1000);
上述代码运行结果:
注意事项:
1. 由于QTimer并不保证定时器事件的严格准确性,因此使用QTimer的应用程序不应该把定时器事件作为实时信号事件来处理。 如果QTimer在Linux上运行,那么通常会出现最多或少数几毫秒的时间误差,这与其他应用程序的运行和负载同时影响。 QObject类提供了一个`timerEvent()`函数,可以实现更精确的计时器。
2. 在大多数情况下,建议将定时器连接到QObject::startTimer()函数,并在哪里实现`timerEvent()`事件,这种方式能够避免多个计时器事件同时达到时可能引起的不稳定现象。另外要保证在计时器事件实现中,响应时间足够的短并且不会由于事件的阻塞导致主事件循环的失调。
3. QTimer的运行可能会占用系统大量资源,如果过于频繁的使用定时器,会导致程序变得缓慢或崩溃,因此应该根据需要慎重使用。定时器的使用通常用于UI界面、后台定时任务等场景。
4. 如果QTimer的间隔设置过小,也可能会出现定时器的不稳定性,所以在应用程序需要精细定时的情况下,应小心使用QTimer。
总的来说,定时任务虽然简单,但是要注意细节,做好异常处理。