計時器

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 () 槽以刷新時鍾的顯示。