Qt C++ | QTimer经验总结

QTimer Class

QTimer类提供重复计时器和单次计时器:

  • 头文件:  #include <QTimer> 
  • qmake:   QT += core
  • 继承自:   QObject

定时器信号

voidtimeout()

公共函数

Qt C++ | QTimer经验总结

Qt::TimerType 枚举定义了 Qt 中不同类型的定时器。它包含以下值:

**Qt::PreciseTimer:**高精度定时器,用于需要精确定时的情况,例如动画或音频处理。

**Qt::CoarseTimer:**低精度定时器,用于不需要精确定时的情况,例如 GUI 更新或用户输入处理。

**Qt::VeryCoarseTimer:**非常低精度定时器,用于不需要精确定时且可以容忍较大延迟的情况,例如后台任务或网络请求。

示例:

QTimer timer;

// 设置定时器类型为高精度
timer.setTimerType(Qt::PreciseTimer);

// 设置定时器类型为低精度
timer.setTimerType(Qt::CoarseTimer);

用法:

Qt::TimerType 枚举用于指定定时器的精度。高精度定时器在需要精确定时的情况下使用,而低精度定时器在不需要精确定时的情况下使用。

优点:

  • 灵活性:它允许根据需要选择定时器的精度。
  • 跨平台:它可以在所有支持 Qt 的平台上使用。
  • 易于使用:它可以通过 setTimerType() 函数轻松设置。

项目巩固

Qt C++ | QTimer经验总结

【1】mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private Q_SLOTS:
    void timerStackSlot();
    void timerPtrSlot();

    void on_pb_timerStack_clicked();

    void on_pb_timerPtr_clicked();

private:
    Ui::MainWindow *ui;

    // 栈定时器 自动销毁
    QTimer timerStack;
    // 指针定时器  需要手动销毁
    QTimer *timerPtr = nullptr;
};
#endif // MAINWINDOW_H

【2】mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 栈定时器
    connect(&this->timerStack,&QTimer::timeout,this,&MainWindow::timerStackSlot);
    this->timerStack.setInterval(5000); // 5s 预设还未真正开启定时器
    this->timerStack.start(); // 开启定时器

    // 获取预设时间
    qDebug()<<"timerStack.interval : "<< this->timerStack.interval();
    // 获取他的基类
    qDebug()<<"timerStack.inherits : "<< this->timerStack.inherits("QObject");
    // 定时器是不是单次
    qDebug()<<"timerStack.isSingleShot : "<< this->timerStack.isSingleShot();
    // 定时器ID
    qDebug()<<"timerStack.timerId : "<< this->timerStack.timerId();

    // 指针定时器
    this->timerPtr = new QTimer(this);
    connect(this->timerPtr,&QTimer::timeout,this,&MainWindow::timerPtrSlot);
    this->timerPtr->start(3000); // 3s
    // 定时器ID 如果计时器正在运行,则返回计时器的ID;否则返回-1。
    qDebug()<<"timerPtr->timerId : "<< timerPtr->timerId();

    // 单次定时器 无需创建对象
    QTimer *timer = new QTimer();
    timer->setSingleShot(true); // 单次定时
    // 设置定时器类型为高精度
    timer->setTimerType(Qt::TimerType::PreciseTimer);
    timer->start(1000); // 以1000毫秒为单位设置超时时间
    // 定时器ID
    qDebug()<<"timer->timer : "<< timer->timerId();
    // 槽函数只会执行一次
    QObject::connect(timer, &QTimer::timeout, this, [timer]{
        // 比如做一些开机初始化
         qDebug()<<"isSingleShot : "<<timer->isSingleShot(); // 如果用栈不会打印,1s的时候构造函数早已执行结束,指针需要程序员手动释放
         // 做完任务 释放指针
         timer->deleteLater();
    });

    // 单次更简洁的写法 静态函数
    // 创建一个单次定时器,在 5 秒后触发
    //QTimer::singleShot(5000, this, SLOT(onTimeout()));
    QTimer::singleShot(5000, this, []{
        // 初始化任务
        qDebug()<<"读个简单的文件";
    });
}

MainWindow::~MainWindow()
{
    qDebug()<<"MainWindow::~MainWindow"<<endl;

    // 定时器的销毁


    this->timerPtr->stop();

    delete this->timerPtr; // 安全的销毁
    this->timerPtr = nullptr;

    delete ui;
}

// 栈定时器槽函数
void MainWindow::timerStackSlot()
{
    // 经过测试剩余时间刚好等于预设的1000ms = 1s
    qDebug()<<"[timerStackSlot]->remainingTime : "<<this->timerStack.remainingTime()<<endl;
}

// 中途获取栈定时器剩余时间,然后以这个剩余时间继续定时器
void MainWindow::on_pb_timerStack_clicked()
{
    qDebug()<<"[on_pb_timerStack_clicked]->remainingTime : "<<this->timerStack.remainingTime()<<endl;
    ui->label_timerStack->setText(QString::number(this->timerStack.remainingTime()));
}

// 槽函数不在举例
void MainWindow::timerPtrSlot()
{

}
// 槽函数不在举例
void MainWindow::on_pb_timerPtr_clicked()
{

}

【3】mainwindow.ui

Qt C++ | QTimer经验总结

【4】main.cpp


#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

QTimer 使用注意事项

使用 QTimer 时,需要注意以下事项:

  • 在事件循环之外删除计时器:始终在事件循环之外删除计时器,因为在事件循环中删除它可能会导致崩溃。
  • 使用单次计时器:对于只触发一次的计时器,应使用 QTimer::singleShot() 方法。
  • 避免过度使用计时器:计时器会占用 CPU 时间,因此避免过度使用它们。
  • 使用高精度计时器:对于需要高精度的计时任务,可以使用 QElapsedTimer 类。
  • 在销毁相关对象之前销毁计时器:如果计时器与其他对象(例如线程或窗口)关联,请确保在销毁这些对象之前销毁计时器。

最佳实践

对于大多数情况,建议直接使用 delete 来删除计时器,如下所示:

timer->stop();
delete timer;
timer = nullptr;

这将立即删除计时器,并确保在释放内存之前停止它。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论