Recherche…
Remarques
QTimer peut également être utilisé pour demander à une fonction de s'exécuter dès que la boucle d'événement a traité tous les autres événements en attente. Pour ce faire, utilisez un intervalle de 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
});
Exemple simple
L'exemple suivant montre comment utiliser un QTimer
pour appeler un logement toutes les 1 secondes.
Dans l'exemple, nous utilisons un QProgressBar
pour mettre à jour sa valeur et vérifier que le minuteur fonctionne correctement.
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 avec fonction Lambda comme fente
Si un minuteur unique est requis, il est pratique d'avoir le logement comme fonction lambda à l'endroit où la minuterie est déclarée:
QTimer::singleShot(1000, []() { /*Code here*/ } );
A cause de ce bogue (QTBUG-26406) , c’est bien possible puisque Qt5.4.
Dans les versions précédentes de Qt5, cela devait être fait avec plus de code de plaque de chaudière:
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, [=]() {
/*Code here*/
timer->deleteLater();
} );
Utiliser QTimer pour exécuter du code sur le thread principal
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));
}
Ceci est utile lorsque vous devez mettre à jour un élément de l'interface utilisateur à partir d'un thread. Gardez à l'esprit la durée de vie de toutes les références de rappel.
DispatchToMainThread([]
{
// main thread
// do UI work here
});
Le même code pourrait être adapté pour exécuter du code sur tout thread exécutant la boucle d'événement Qt, implémentant ainsi un mécanisme de répartition simple.
Utilisation de base
QTimer
ajoute la fonctionnalité pour qu'une fonction / un emplacement spécifique soit appelé après un certain intervalle (plusieurs fois ou juste une fois).
Le QTimer
permet ainsi à une application GUI de "vérifier" les choses régulièrement ou de gérer les délais d'attente sans avoir à démarrer manuellement un thread supplémentaire pour cela et à faire attention aux conditions de course, car le timer sera géré dans la boucle d'événement principal.
Une minuterie peut simplement être utilisée comme ceci:
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
Le temporisateur déclenche le signal de timeout
la fin du temps et celui-ci sera appelé dans la boucle d'événement principal.
QTimer :: singleShot utilisation simple
Le QTimer :: singleShot est utilisé pour appeler un slot / lambda de manière asynchrone après n ms.
La syntaxe de base est la suivante:
QTimer::singleShot(myTime, myObject, SLOT(myMethodInMyObject()));
avec myTime le temps en ms, myObject l'objet qui contient la méthode et myMethodInMyObject l'emplacement à appeler
Donc, par exemple, si vous voulez avoir une minuterie qui écrit une ligne de débogage "bonjour!" toutes les 5 secondes:
.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();
...
};