QObject 是所有 Qt 對象的基類,在 Qt 中提供基本計時器支持。采用 QObject::startTimer (),采用間隔 (以毫秒為單位) 作為自變量啓動計時器。函數返迴唯一整型計時器 ID。然後以常規間隔激發計時器,直到明確調用 QObject::killTimer () 采用該計時器 ID。
代替直接處理計時器 ID,可以使用 QBasicTimer . QBasicTimer 是值類, RAII 包裹器圍繞計時器 ID。啓動計時器采用 QBasicTimer::start (),和停止它采用 QBasicTimer::stop () (後者還會被調用當銷毀時)。要使用 QBasicTimer ,必須重實現 timerEvent () 在類 (必須是子類化的 QObject ),並在那裏處理計時器事件。
此機製要工作,應用程序必須在事件循環中運行。可以啓動事件循環采用 QApplication::exec ()。當計時器激發時,應用程序發送 QTimerEvent ,並控製流離開事件循環,直到計時器事件被處理。這隱含計時器無法被激發,當應用程序忙於做某些事情時。換句話說:計時器精度從屬應用程序的粒度。
在多綫程應用程序中,可以在擁有事件循環的任何綫程中使用計時器機製。要從非 GUI 綫程啓動事件循環,使用 QThread::exec ()。Qt 使用對象的 綫程親緣關係 確定哪個綫程將交付 QTimerEvent 。因此,必須啓動和停止對象綫程中的所有計時器;為另一綫程中的對象啓動計時器,是不可能的。
計時器功能的主要 API 是 QTimer . QTimer 以有符號整數存儲間隔,把它支持的最大間隔,以有符號整數限製到可以擬閤的毫秒數 (實際上,這大約是 24 天的周期)。
Qt 6.8 引入瞭
QChronoTimer
類。2 個類的主要差異是
QChronoTimer
支持更大間隔範圍和更高精度 (
std::chrono::nanoseconds
)。對於
QTimer
最大支持間隔為 ±24 天,而
QChronoTimer
是 ±292 年。若隻需要毫秒分辨率和 ±24 天範圍,可以繼續使用
QTimer
。注意,
QChronoTimer
的存在主要是因為
QTimer
的精度無法被改為
std::chrono::nanoseconds
不破壞二進製兼容性。
計時器的精度從屬底層 OS (操作係統)。Windows 2000 擁有 15ms 精度;我們有測試過其它係統,可以處理 1ms 間隔。
QTimer 提供發射信號的常規計時器,當計時器激發時,並繼承自 QObject 因此,它能很好適應大多數 Qt 程序的所有權結構。正常使用它的方式像這樣:
QTimer *timer = new QTimer(1s, this);
connect(timer, &QTimer::timeout, this, &MyWidget::processOneThing);
timer->start();
auto *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyWidget::processOneThing);
timer->setInterval(1s);
timer->start();
The
QTimer
對象被製作成子級對於
this
對象,因此當
this
被銷毀,計時器也被銷毀。接下來,
timeout
() 信號被連接到將做工作的槽,可以把計時器間隔傳遞給構造函數,或稍後設置采用 setInterval()。
QTimer 還為單發計時器提供靜態函數。例如:
MyWidget widget;
QTimer::singleShot(200ms, &widget, &MyWidget::updateCaption);
200 毫秒後這執行代碼行,
updateCaption()
槽將被調用。
For QTimer 要工作,應用程序必須擁有事件循環;也就是說,必須調用 QCoreApplication::exec () 在某些地方。纔交付計時器事件,當事件循環在運行時。
在多綫程應用程序中,可以使用 QTimer 在擁有事件循環的任何綫程中。要從非 GUI 綫程啓動事件循環,使用 QThread::exec ()。Qt 使用計時器的 綫程親緣關係 確定哪個綫程將發射 timeout () 信號。因此這,必須在其綫程中啓動和停止計時器;從另一綫程啓動計時器,是不可能的。
The
指針式時鍾
範例展示如何使用
QTimer
以按定期間隔重新繪製 Widget。來自
AnalogClock
的實現:
AnalogClock::AnalogClock(QWidget *parent) : QWidget(parent) { QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update)); timer->start(1000); setWindowTitle(tr("Analog Clock")); resize(200, 200); }
每秒, QTimer 會調用 QWidget::update () 槽以刷新時鍾的顯示。