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();
    ...
};


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow