サーチ…


備考

QTimerは、イベントループが他のすべての保留イベントを処理するとすぐに機能を要求するためにも使用できます。これを行うには、0ミリ秒の間隔を使用します。

// 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
});

簡単な例

次の例は、 QTimerを使用して1秒ごとにスロットを呼び出す方法を示しています。

この例では、 QProgressBarを使用して値を更新し、タイマーが正常に動作していることを確認します。

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

スロットとしてのラムダ機能付きのシングルットタイマ

単体タイマが必要な場合は、タイマーが宣言されている場所でラムダ関数としてスロットを使用すると便利です。

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

このバグ(QTBUG-26406)のおかげで 、これはQt5.4以来可能です。

以前のQt5バージョンでは、より多くのボイラープレートコードを使用しなければなりませんでした。

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

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

QTimerを使ってメインスレッドでコードを実行する

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

これは、UI要素をスレッドから更新する必要がある場合に便利です。コールバックが参照するものは生涯にわたって覚えておいてください。

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

同じコードをQtイベントループを実行する任意のスレッド上でコードを実行するように適合させることができ、したがって簡単なディスパッチ機構を実装することができる。

基本的な使用法

QTimerは、一定の間隔の後に(繰り返しまたは一度だけ)呼び出される特定の機能/スロットを持つ機能を追加します。

したがって、 QTimerは、タイマーがメインイベントループで処理されるため、GUIアプリケーションが定期的に物事をチェックしたり、タイムアウトを手動で処理したり、競合状態に注意したりすることなく 、タイムアウト処理することができます。

タイマーは以下のように単純に使用できます:

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

時間が終了するとタイマーがtimeout信号をトリガし、これがメインイベントループで呼び出されます。

QTimer :: singleShot簡単な使い方

QTimer :: singleShotは、n ms後にスロット/ラムダを非同期に呼び出すために使用されます。

基本的な構文は次のとおりです。

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

myTimeの場合はms、 myObjectの場合はメソッド、 myMethodInMyObjectの場合はスロット

たとえば、デバッグ行 "hello!"を書いているタイマーを持っているとします。 5秒ごと:

.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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow