Qt定時器類QTimer使用詳解與注意事項
前言
Qt定時器類QTimer是一個用于重復(fù)執(zhí)行或延遲執(zhí)行函數(shù)的類。它可以在一定時間間隔內(nèi)發(fā)送一個信號,也可以在指定的時間后發(fā)送一個信號。QTimer是一個基于事件的定時器,即它使用Qt的事件循環(huán)來觸發(fā)定時器事件。
要使用它,只需創(chuàng)建一個QTimer類對象,然后調(diào)用其 start()
函數(shù)開啟定時器,此后QTimer對象就會周期性的發(fā)出 timeout()
信號。我們先來了解一下這個類的相關(guān)API。
以下是QTimer常用的函數(shù):
QTimer(int interval, QObject * parent = nullptr)//構(gòu)造函數(shù),創(chuàng)建一個新的QTimer對象,間隔時間由`interval`指定。`parent`參數(shù)可以設(shè)置QObject的父對象。 start(int msec = 0)// 啟動or重新啟動計時器。 stop()// 停止計時器。 setInterval(int interval)// 設(shè)置計時間隔。 setSingleShot(bool singleShot)// 設(shè)置計時器方式,若參數(shù)`singleShot`為`true`,則定時器只會在定時時間間隔到達(dá)時發(fā)出一次timeout()信號,否則定時器會一直重復(fù)發(fā)出timeout()信號。 timerId() const// 返回此計時器的標(biāo)識符。 isActive() const// 返回計時器是否處于活動狀態(tài)。
public/slot function
// 構(gòu)造函數(shù) // 如果指定了父對象, 創(chuàng)建的堆內(nèi)存可以自動析構(gòu) QTimer::QTimer(QObject *parent = nullptr); // 設(shè)置定時器時間間隔為 msec 毫秒 // 默認(rèn)值是0,一旦窗口系統(tǒng)事件隊列中的所有事件都已經(jīng)被處理完,一個時間間隔為0的QTimer就會觸發(fā) void QTimer::setInterval(int msec); // 獲取定時器的時間間隔, 返回值單位: 毫秒 int QTimer::interval() const; // 根據(jù)指定的時間間隔啟動或者重啟定時器, 需要調(diào)用 setInterval() 設(shè)置時間間隔 [slot] void QTimer::start(); // 啟動或重新啟動定時器,超時間隔為msec毫秒。 [slot] void QTimer::start(int msec); // 停止定時器。 [slot] void QTimer::stop(); // 設(shè)置定時器精度 /* 參數(shù): - Qt::PreciseTimer -> 精確的精度, 毫秒級 - Qt::CoarseTimer -> 粗糙的精度, 和1毫秒的誤差在5%的范圍內(nèi), 默認(rèn)精度 - Qt::VeryCoarseTimer -> 非常粗糙的精度, 精度在1秒左右 */ void QTimer::setTimerType(Qt::TimerType atype); Qt::TimerType QTimer::timerType() const; // 獲取當(dāng)前定時器的精度 // 如果定時器正在運行,返回true; 否則返回false。 bool QTimer::isActive() const; // 判斷定時器是否只觸發(fā)一次 bool QTimer::isSingleShot() const; // 設(shè)置定時器是否只觸發(fā)一次, 參數(shù)為true定時器只觸發(fā)一次, 為false定時器重復(fù)觸發(fā), 默認(rèn)為false void QTimer::setSingleShot(bool singleShot);
signals
這個類的信號只有一個, 當(dāng)定時器超時時,該信號就會被發(fā)射出來。給這個信號通過 conect()
關(guān)聯(lián)一個槽函數(shù), 就可以在槽函數(shù)中處理超時事件了。
[signal] void QTimer::timeout();
static public function
/* 功能: 在msec毫秒后發(fā)射一次信號, 并且只發(fā)射一次 參數(shù): - msec: 在msec毫秒后發(fā)射信號 - receiver: 接收信號的對象地址 - method: 槽函數(shù)地址 */ [static] void QTimer::singleShot( int msec, const QObject *receiver, PointerToMemberFunction method);
示例(獲取系統(tǒng)時間并且將其顯示到窗口中):
創(chuàng)建名為QTimerTest的項目,在mainwindow.ui文件中創(chuàng)建兩個按鈕和兩個label
上面的“開始計時”按鈕點擊之后,在TextLabel中顯示動態(tài)時間,下面的“開始計時”按鈕點擊之后,只獲取一次當(dāng)前時間。
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); //創(chuàng)建定時器對象 QTimer* timer = new QTimer(this); //修改定時器精度 //timer->setTimerType(QTimer::PreciseTimer); //按鈕的點擊事件 connect(ui->loopBtn,&QPushButton::clicked,this,[=]() { //啟動定時器 if(timer->isActive()) { timer->stop();//關(guān)閉定時器 ui->loopBtn->setText("開始"); } else { ui->loopBtn->setText("關(guān)閉"); timer->start(1000);//1000ms == 1s } } ); connect(timer,&QTimer::timeout,this,[=]() { QTime tm = QTime::currentTime(); //格式化當(dāng)前得到的系統(tǒng)時間 QString tmstr = tm.toString("hh:mm:ss.zzz"); //設(shè)置要顯示的時間 ui->curTime->setText(tmstr); }); //發(fā)射一次信號 connect(ui->onceBtn,&QPushButton::clicked,this,[=]() { //獲取2s以后的系統(tǒng)時間 QTimer::singleShot(2000,this,[=]() { QTime tm = QTime::currentTime(); //格式化當(dāng)前得到的系統(tǒng)時間 QString tmstr = tm.toString("hh:mm:ss.zzz"); //設(shè)置要顯示的時間 ui->onceTime->setText(tmstr); }); }); } MainWindow::~MainWindow() { delete ui; }
運行結(jié)果:
示例主要代碼(每間隔一秒向控制臺發(fā)送一條消息):
//每間隔一秒向控制臺發(fā)送一條信息 connect(timer, &QTimer::timeout, this, [=]() { qDebug() << "This is the QTimer test!"; }); timer->start(1000);
上述代碼運行結(jié)果:
注意事項:
1. 由于QTimer并不保證定時器事件的嚴(yán)格準(zhǔn)確性,因此使用QTimer的應(yīng)用程序不應(yīng)該把定時器事件作為實時信號事件來處理。 如果QTimer在Linux上運行,那么通常會出現(xiàn)最多或少數(shù)幾毫秒的時間誤差,這與其他應(yīng)用程序的運行和負(fù)載同時影響。 QObject類提供了一個`timerEvent()`函數(shù),可以實現(xiàn)更精確的計時器。
2. 在大多數(shù)情況下,建議將定時器連接到QObject::startTimer()函數(shù),并在哪里實現(xiàn)`timerEvent()`事件,這種方式能夠避免多個計時器事件同時達(dá)到時可能引起的不穩(wěn)定現(xiàn)象。另外要保證在計時器事件實現(xiàn)中,響應(yīng)時間足夠的短并且不會由于事件的阻塞導(dǎo)致主事件循環(huán)的失調(diào)。
3. QTimer的運行可能會占用系統(tǒng)大量資源,如果過于頻繁的使用定時器,會導(dǎo)致程序變得緩慢或崩潰,因此應(yīng)該根據(jù)需要慎重使用。定時器的使用通常用于UI界面、后臺定時任務(wù)等場景。
4. 如果QTimer的間隔設(shè)置過小,也可能會出現(xiàn)定時器的不穩(wěn)定性,所以在應(yīng)用程序需要精細(xì)定時的情況下,應(yīng)小心使用QTimer。
總的來說,定時任務(wù)雖然簡單,但是要注意細(xì)節(jié),做好異常處理。
總結(jié)
到此這篇關(guān)于Qt定時器類QTimer使用詳解與注意事項的文章就介紹到這了,更多相關(guān)Qt定時器類QTimer內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ Boost Chrono實現(xiàn)計時碼表流程詳解
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱2022-11-11C++訪問std::variant類型數(shù)據(jù)的幾種方式小結(jié)
std::variant是?C++17中引入的一個新的類模板,提供了一種存儲不同類型的值的方式,本文主要介紹了C++訪問std::variant類型數(shù)據(jù)的幾種方式小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-02-02C語言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實現(xiàn)
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實現(xiàn)的相關(guān)資料,這里提供實現(xiàn)實例,希望通過本文能幫助到大家,需要的朋友可以參考下2017-08-08