Zeitgeber
QObject, die Basisklasse aller Qt-Objekte, bietet die grundlegende Timer-Unterstützung in Qt. Mit QObject::startTimer() starten Sie einen Timer mit einem Intervall in Millisekunden als Argument. Die Funktion gibt eine eindeutige integrale Timer-ID zurück. Der Timer wird dann in regelmäßigen Abständen ausgelöst, bis Sie QObject::killTimer() explizit mit dieser Timer-ID aufrufen.
Anstatt Timer-IDs direkt zu verarbeiten, können Sie QBasicTimer verwenden. QBasicTimer ist ein RAII-Wrapper der Werteklasse, der eine Timer-ID umgibt. Sie starten den Timer mit QBasicTimer::start() und stoppen ihn mit QBasicTimer::stop() (letzteres wird auch bei der Zerstörung aufgerufen). Um QBasicTimer zu verwenden, müssen Sie timerEvent() in Ihrer Klasse (die eine Unterklasse von QObject sein muss) reimplementieren und das Timer-Ereignis dort behandeln.
Damit dieser Mechanismus funktioniert, muss die Anwendung in einer Ereignisschleife laufen. Sie können eine Ereignisschleife mit QApplication::exec() starten. Wenn ein Timer ausgelöst wird, sendet die Anwendung eine QTimerEvent, und der Kontrollfluss verlässt die Ereignisschleife, bis das Timer-Ereignis verarbeitet ist. Dies bedeutet, dass ein Zeitgeber nicht ausgelöst werden kann, während Ihre Anwendung mit etwas anderem beschäftigt ist. Mit anderen Worten: Die Genauigkeit von Zeitgebern hängt von der Granularität Ihrer Anwendung ab.
In Multithread-Anwendungen können Sie den Timer-Mechanismus in jedem Thread verwenden, der eine Ereignisschleife hat. Um eine Ereignisschleife von einem Nicht-GUI-Thread aus zu starten, verwenden Sie QThread::exec(). Qt verwendet die thread affinity des Objekts, um zu bestimmen, welcher Thread die QTimerEvent liefern wird. Aus diesem Grund müssen Sie alle Timer im Thread des Objekts starten und stoppen; es ist nicht möglich, Timer für Objekte in einem anderen Thread zu starten.
Die Haupt-API für die Timer-Funktionalität ist QTimer. QTimer speichert das Intervall in einem vorzeichenbehafteten Integer, was das maximal unterstützte Intervall auf die Anzahl der Millisekunden begrenzt, die in einen vorzeichenbehafteten Integer passen (in der Praxis ist dies ein Zeitraum von etwa 24 Tagen).
Mit Qt 6.8 wurde die Klasse QChronoTimer eingeführt. Der Hauptunterschied zwischen den beiden Klassen ist, dass QChronoTimer einen größeren Intervallbereich und eine höhere Genauigkeit unterstützt (std::chrono::nanoseconds
). Für QTimer beträgt das maximal unterstützte Intervall ±24 Tage, während es für QChronoTimer ±292 Jahre beträgt. Wenn Sie nur eine Auflösung von Millisekunden und einen Bereich von ±24 Tagen benötigen, können Sie weiterhin QTimer verwenden.
Die Genauigkeit der Timer hängt von dem zugrunde liegenden Betriebssystem ab. Windows 2000 hat eine Genauigkeit von 15 ms; andere Systeme, die wir getestet haben, können mit 1 ms-Intervallen umgehen.
QChronoTimer bietet reguläre Timer, die ein Signal ausgeben, wenn der Timer ausgelöst wird, und erbt von QObject, so dass er gut in die Eigentümerstruktur der meisten Qt-Programme passt. Der normale Weg, ihn zu benutzen, ist wie folgt:
QChronoTimer *timer = new QChronoTimer(1s, this); connect(timer, &QChronoTimer::timeout, this, &MyWidget::processOneThing); timer->start(); QChronoTimer *timer = new QChronoTimer(this); connect(timer, &QChronoTimer::timeout, this, &MyWidget::processOneThing); timer->setInterval(1s); timer->start();
Das Objekt QChronoTimer wird zu einem Kind des Objekts this
gemacht, so dass, wenn this
zerstört wird, auch der Timer zerstört wird. Als nächstes wird das timeout()-Signal mit dem Slot verbunden, der die Arbeit verrichten wird, das Timer-Intervall kann entweder an den Konstruktor übergeben oder später mit setInterval() gesetzt werden.
QChronoTimer bietet auch statische Funktionen für Single-Shot-Timer. Zum Beispiel:
MyWidget widget; QChronoTimer::singleShot(200ms, &widget, &MyWidget::updateCaption);
200ms nach Ausführung dieser Codezeile wird der updateCaption()
Slot aufgerufen.
Damit QChronoTimer funktioniert, müssen Sie eine Ereignisschleife in Ihrer Anwendung haben, d.h. Sie müssen irgendwo QCoreApplication::exec() aufrufen. Timer-Ereignisse werden nur geliefert, während die Ereignisschleife läuft.
In Multithread-Anwendungen können Sie QChronoTimer in jedem Thread verwenden, der eine Ereignisschleife hat. Um eine Ereignisschleife aus einem Nicht-GUI-Thread zu starten, verwenden Sie QThread::exec(). Qt verwendet die thread affinity des Timers, um zu bestimmen, welcher Thread das Signal timeout() ausgibt. Aus diesem Grund müssen Sie den Timer in seinem Thread starten und stoppen; es ist nicht möglich, einen Timer von einem anderen Thread aus zu starten.
Das Beispiel der analogen Uhr zeigt, wie man QChronoTimer verwendet, um ein Widget in regelmäßigen Abständen neu zu zeichnen. Aus der Implementierung von AnalogClock
:
AnalogClock::AnalogClock(QWidget *parent) : QWidget(parent) { auto *timer = new QChronoTimer(1s, this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update)); timer->start(); ... ... setWindowTitle(tr("Analog Clock")); resize(200, 200); }
Jede Sekunde wird QChronoTimer den Slot QWidget::update() aufrufen, um die Anzeige der Uhr zu aktualisieren.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.