Zoeken…
Opmerkingen
QTimer kan ook worden gebruikt om een functie aan te vragen die moet worden uitgevoerd zodra de gebeurtenislus alle andere lopende gebeurtenissen heeft verwerkt. Gebruik hiervoor een interval van 0 ms.
// option 1: Set the interval to 0 explicitly.
QTimer *timer = new QTimer;
timer->setInterval( 0 );
timer->start();
// option 2: Passing 0 with the start call will set the interval as well.
QTimer *timer = new QTimer;
timer->start( 0 );
// option 3: use QTimer::singleShot with interval 0
QTimer::singleShot(0, [](){
// do something
});
Eenvoudig voorbeeld
Het volgende voorbeeld laat zien hoe u een QTimer
om elke 1 seconde een slot op te roepen.
In het voorbeeld gebruiken we een QProgressBar
om de waarde bij te werken en te controleren of de timer correct werkt.
main.cpp
#include <QApplication>
#include "timer.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Timer timer;
timer.show();
return app.exec();
}
timer.h
#ifndef TIMER_H
#define TIMER_H
#include <QWidget>
class QProgressBar;
class Timer : public QWidget
{
Q_OBJECT
public:
Timer(QWidget *parent = 0);
public slots:
void updateProgress();
private:
QProgressBar *progressBar;
};
#endif
timer.cpp
#include <QLayout>
#include <QProgressBar>
#include <QTimer>
#include "timer.h"
Timer::Timer(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout();
progressBar = new QProgressBar();
progressBar->setMinimum(0);
progressBar->setMaximum(100);
layout->addWidget(progressBar);
setLayout(layout);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Timer::updateProgress);
timer->start(1000);
setWindowTitle(tr("Timer"));
resize(200, 200);
}
void Timer::updateProgress()
{
progressBar->setValue(progressBar->value()+1);
}
timer.pro
QT += widgets
HEADERS = \
timer.h
SOURCES = \
main.cpp \
timer.cpp
Singleshot-timer met Lambda-functie als slot
Als een enkelvoudige timer is vereist, is het erg handig om de sleuf als lambda-functie precies op de plaats te hebben waar de timer wordt aangegeven:
QTimer::singleShot(1000, []() { /*Code here*/ } );
Vanwege deze bug (QTBUG-26406) is deze manier alleen mogelijk sinds Qt5.4.
In eerdere Qt5-versies moet dit worden gedaan met meer ketelplaatcode:
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, [=]() {
/*Code here*/
timer->deleteLater();
} );
QTimer gebruiken om code op hoofdthread uit te voeren
void DispatchToMainThread(std::function<void()> callback)
{
// any thread
QTimer* timer = new QTimer();
timer->moveToThread(qApp->thread());
timer->setSingleShot(true);
QObject::connect(timer, &QTimer::timeout, [=]()
{
// main thread
callback();
timer->deleteLater();
});
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
}
Dit is handig wanneer u een UI-element van een thread moet bijwerken. Houd rekening met de levensduur van alles wat de terugbelverwijzingen zijn.
DispatchToMainThread([]
{
// main thread
// do UI work here
});
Dezelfde code kan worden aangepast om code uit te voeren op elke thread die de Qt-gebeurtenislus uitvoert, waardoor een eenvoudig verzendmechanisme wordt geïmplementeerd.
Basisgebruik
QTimer
voegt de functionaliteit toe om een specifieke functie / slot te hebben die na een bepaald interval wordt opgeroepen (herhaald of slechts eenmaal).
De QTimer
dus mogelijk dat een GUI-applicatie dingen regelmatig "checkt" of time-outs afhandelt zonder hiervoor handmatig een extra thread te starten en voorzichtig moet zijn met raceomstandigheden, omdat de timer in de hoofdevenementlus wordt behandeld.
Een timer kan eenvoudig als volgt worden gebruikt:
QTimer* timer = new QTimer(parent); //create timer with optional parent object
connect(timer,&QTimer::timeout,[this](){ checkProgress(); }); //some function to check something
timer->start(1000); //start with a 1s interval
De timer activeert het timeout
signaal als de tijd voorbij is en dit wordt in de hoofdgebeurtenislus opgeroepen.
QTimer :: eenvoudig gebruik van singleShot
De QTimer :: singleShot wordt gebruikt om een slot / lambda asynchroon na n ms aan te roepen.
De basissyntaxis is:
QTimer::singleShot(myTime, myObject, SLOT(myMethodInMyObject()));
met myTime de tijd in ms, myObject het object dat de methode bevat en myMethodInMyObject de aan te roepen slot
Dus bijvoorbeeld als u een timer wilt hebben die een foutopsporingsregel schrijft "hallo!" om de 5 seconden:
cpp
void MyObject::startHelloWave()
{
QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}
void MyObject::helloWave()
{
qDebug() << "hello !";
QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}
.hh
class MyObject : public QObject {
Q_OBJECT
...
void startHelloWave();
private slots:
void helloWave();
...
};