サーチ…
備考
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();
...
};