Buscar..


Observaciones

QTimer también se puede usar para solicitar que una función se ejecute tan pronto como el bucle de eventos haya procesado todos los demás eventos pendientes. Para ello, utiliza un intervalo 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
});

Ejemplo simple

El siguiente ejemplo muestra cómo usar un QTimer para llamar a una ranura cada 1 segundo.

En el ejemplo, usamos una QProgressBar para actualizar su valor y comprobar que el temporizador funciona correctamente.

main.cpp

#include <QApplication>

#include "timer.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Timer timer;
    timer.show();

    return app.exec();
}

temporizador.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

Temporizador Singleshot con función Lambda como ranura

Si se requiere un temporizador de disparo único, es bastante práctico tener la ranura como función lambda en el lugar donde se declara el temporizador:

QTimer::singleShot(1000, []() { /*Code here*/ } );

Debido a este error (QTBUG-26406) , esto solo es posible desde Qt5.4.

En versiones anteriores de Qt5 se debe hacer con más código de placa de caldera:

  QTimer *timer = new QTimer(this);
  timer->setSingleShot(true);

  connect(timer, &QTimer::timeout, [=]() {
    /*Code here*/
    timer->deleteLater();
  } );

Usando QTimer para ejecutar código en el hilo 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));
}

Esto es útil cuando necesita actualizar un elemento UI desde un hilo. Tenga en cuenta toda la vida de las referencias de devolución de llamada.

DispatchToMainThread([]
{
    // main thread
    // do UI work here
});

El mismo código podría adaptarse para ejecutar código en cualquier subproceso que ejecute el bucle de eventos Qt, implementando así un mecanismo de envío simple.

Uso básico

QTimer agrega la funcionalidad para tener una función / ranura específica llamada después de un cierto intervalo (repetidamente o solo una vez).

El QTimer tanto, permite que una aplicación GUI "verifique" las cosas regularmente o maneje los tiempos de espera sin tener que iniciar manualmente un subproceso adicional para esto y tenga cuidado con las condiciones de la carrera, ya que el temporizador se manejará en el bucle del evento principal.

Un temporizador se puede utilizar simplemente así:

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

El temporizador dispara la señal de timeout cuando termina el tiempo y esto se llamará en el bucle del evento principal.

QTimer :: singleShot uso simple

El QTimer :: singleShot se utiliza para llamar a una ranura / lambda de forma asíncrona después de n ms.

La sintaxis básica es:

QTimer::singleShot(myTime, myObject, SLOT(myMethodInMyObject()));

con myTime el tiempo en ms, myObject el objeto que contiene el método y myMethodInMyObject la ranura para llamar

Así, por ejemplo, si desea tener un temporizador que escriba una línea de depuración "¡hola!" cada 5 segundos:

.cpp

void MyObject::startHelloWave()
{
    QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}

void MyObject::helloWave()
{
    qDebug() << "hello !";
    QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}

.S.S

class MyObject : public QObject {
    Q_OBJECT
    ...
    void startHelloWave();

private slots:
    void helloWave();
    ...
};


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow