QTimer Class
QTimer类提供重复计时器和单次计时器:
- 头文件: #include <QTimer>
- qmake: QT += core
- 继承自: QObject
定时器信号
void | timeout() |
公共函数
Qt::TimerType 枚举定义了 Qt 中不同类型的定时器。它包含以下值:
**Qt::PreciseTimer:**高精度定时器,用于需要精确定时的情况,例如动画或音频处理。
**Qt::CoarseTimer:**低精度定时器,用于不需要精确定时的情况,例如 GUI 更新或用户输入处理。
**Qt::VeryCoarseTimer:**非常低精度定时器,用于不需要精确定时且可以容忍较大延迟的情况,例如后台任务或网络请求。
示例:
QTimer timer;
// 设置定时器类型为高精度
timer.setTimerType(Qt::PreciseTimer);
// 设置定时器类型为低精度
timer.setTimerType(Qt::CoarseTimer);
用法:
Qt::TimerType
枚举用于指定定时器的精度。高精度定时器在需要精确定时的情况下使用,而低精度定时器在不需要精确定时的情况下使用。
优点:
- 灵活性:它允许根据需要选择定时器的精度。
- 跨平台:它可以在所有支持 Qt 的平台上使用。
- 易于使用:它可以通过
setTimerType()
函数轻松设置。
项目巩固
【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
【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 举报,一经查实,本站将立刻删除。