Qt定时器类QTimer使用详解与注意事项

 更新时间:2023年10月07日 16:19:59   作者:小梁今天敲代码了吗  
Qt提供了两种定时器,一种是QObject类的定时器,另一种是QTimer类的定时器,这篇文章主要给大家介绍了关于Qt定时器类QTimer使用与注意事项的相关资料,需要的朋友可以参考下

前言

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。

总的来说,定时任务虽然简单,但是要注意细节,做好异常处理。

总结

到此这篇关于Qt定时器类QTimer使用详解与注意事项的文章就介绍到这了,更多相关Qt定时器类QTimer内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现LeetCode(104.二叉树的最大深度)

    C++实现LeetCode(104.二叉树的最大深度)

    这篇文章主要介绍了C++实现LeetCode(104.二叉树的最大深度),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • LeetCode题解C++生成每种字符都是奇数个的字符串

    LeetCode题解C++生成每种字符都是奇数个的字符串

    这篇文章主要为大家介绍了LeetCode题解C++生成每种字符都是奇数个的字符串示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • C语言实现简易版扫雷的完整过程

    C语言实现简易版扫雷的完整过程

    这篇文章主要给大家介绍了关于利用C语言如何实现简易版扫雷的完整过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • C语言数组和指针的问题一道非常值得深思的笔试题

    C语言数组和指针的问题一道非常值得深思的笔试题

    今天小编就为大家分享一篇关于C语言数组和指针的问题一道非常值得深思的笔试题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • VC++实现输出GIF到窗体并显示GIF动画的方法

    VC++实现输出GIF到窗体并显示GIF动画的方法

    这篇文章主要介绍了VC++实现输出GIF到窗体并显示GIF动画的方法,需要的朋友可以参考下
    2014-07-07
  • C++序列操作函数学习最全指南

    C++序列操作函数学习最全指南

    这篇文章主要给大家介绍了关于C++序列操作函数学习的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • C++类与对象深入之引用与内联函数与auto关键字及for循环详解

    C++类与对象深入之引用与内联函数与auto关键字及for循环详解

    朋友们好,这篇播客我们继续C++的初阶学习,现在对一些C++的入门知识做了些总结,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步
    2022-06-06
  • C语言中getchar和putchar的使用方法详解

    C语言中getchar和putchar的使用方法详解

    我们知道scanf函数可以从键盘输入信息,而printf则可以输出信息,同样地,getchar和putchar也有同样的功能,下面我来给大家介绍putchar和getchar的使用方法,需要的朋友可以参考下
    2023-08-08
  • 浅析C++11新特性的Lambda表达式

    浅析C++11新特性的Lambda表达式

    C++11 新增了很多特性,lambda 表达式是其中之一,本文涉及到C++11这次更新中较为重要的lambda表达式。有需要的朋友们可以参考学习。
    2016-08-08
  • 详解C语言初阶基础(2)

    详解C语言初阶基础(2)

    这篇文章主要介绍了C语言中的初阶基础,介绍了其相关概念,具有一定参考价值。需要的朋友可以了解下,希望能够给你带来帮助
    2021-11-11

最新评论