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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow