タイマー

QObjectすべての Qt オブジェクトの基本クラスである Timers は、Qt の基本的なタイマー・サポートを提供します。QObject::startTimer() で、ミリ秒単位でタイマーを開始します。この関数はユニークなタイマーIDを返します。このタイマは、そのタイマIDでQObject::killTimer ()を明示的に呼び出すまで、一定の間隔で起動します。

タイマーIDを直接処理する代わりに、QBasicTimer を使用することもできる。QBasicTimer は、タイマーIDの値クラス、RAIIラッパーである。タイマーを開始するにはQBasicTimer::start ()を使用し、停止するにはQBasicTimer::stop ()を使用する(後者は破棄時にも呼び出される)。QBasicTimer を使用するには、timerEvent() をクラス(QObject のサブクラスでなければなりません)に再実装し、そこでタイマー・イベントを処理する必要があります。

このメカニズムが機能するためには、アプリケーションはイベント・ループの中で実行されなければなりません。QApplication::exec ()でイベント・ループを開始します。タイマーが切れると、アプリケーションはQTimerEvent を送信し、タイマー・イベントが処理されるまで、制御の流れはイベント・ループから離れる。このことは、アプリケーションが他の処理に忙殺されている間は、タイマーが作動しないことを意味します。言い換えれば、タイマーの精度はアプリケーションの粒度に依存します。

マルチスレッド・アプリケーションでは、イベント・ループを持つどのスレッドでもタイマーのメカニズムを使用できます。非GUIスレッドからイベントループを開始するには、QThread::exec ()を使用します。Qtはオブジェクトのthread affinity を使用して、どのスレッドがQTimerEvent を配信するかを決定します。このため、オブジェクトのスレッドですべてのタイマーを開始および停止する必要があります。別のスレッドでオブジェクトのタイマーを開始することはできません。

タイマー機能の主なAPIはQTimer です。QTimer は符号付き整数で間隔を保存し、サポートする最大間隔は符号付き整数に収まるミリ秒数に制限されます(実際には、これは約24日の期間です)。

Qt 6.8 ではQChronoTimer クラスが導入されました。この2つのクラスの主な違いは、QChronoTimer がより大きな間隔と高い精度をサポートしていることです(std::chrono::nanoseconds )。QTimer 、サポートされる最大間隔は±24日ですが、QChronoTimer 、それは±292年です。ミリ秒の分解能と±24日の範囲しか必要ない場合は、QTimer を使い続けることができる。

タイマーの精度は、基盤となるオペレーティング・システムに依存する。Windows 2000の精度は15msであるが、私たちがテストした他のシステムでは1ms間隔を扱うことができる。

QChronoTimer QObject を継承しているため、ほとんどの Qt プログラムの所有構造にうまく適合します。通常の使い方は次のようになります:

        QChronoTimer *timer = new QChronoTimer(1s, this);
        connect(timer, &QChronoTimer::timeout, this, &MyWidget::processOneThing);
        timer->start();
        QChronoTimer *timer = new QChronoTimer(this);
        connect(timer, &QChronoTimer::timeout, this, &MyWidget::processOneThing);
        timer->setInterval(1s);
        timer->start();

QChronoTimer オブジェクトをthis オブジェクトの子オブジェクトにして、this が破壊されたときにタイマーも破壊されるようにします。次に、timeout() シグナルを処理を行うスロットに接続します。タイマーの間隔はコンストラクタに渡すか、後でsetInterval()で設定します。

QChronoTimer また、シングルショットタイマー用の静的関数も用意されている。例えば

        MyWidget widget;
        QChronoTimer::singleShot(200ms, &widget, &MyWidget::updateCaption);

このコード行が実行された200ms後に、updateCaption() スロットが呼び出されます。

QChronoTimer つまり、QCoreApplication::exec ()をどこかで呼び出す必要があります。タイマー・イベントは、イベント・ループが実行されている間だけ配信されます。

マルチスレッド・アプリケーションでは、イベント・ループを持つ任意のスレッドでQChronoTimer を使用できます。GUI以外のスレッドからイベントループを開始するには、QThread::exec ()を使用します。Qtは、タイマーのthread affinity を使用して、どのスレッドがtimeout() シグナルを発信するかを決定します。このため、タイマーを開始したり停止したりするには、そのスレッド内で行う必要があります。

アナログ時計の例では、QChronoTimer を使用して、一定間隔でウィジェットを再描画する方法を示しています。AnalogClock の実装から:

AnalogClock::AnalogClock(QWidget *parent)

    : QWidget(parent)
{
    auto *timer = new QChronoTimer(1s, this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
    timer->start();
    ...
    ...
    setWindowTitle(tr("Analog Clock"));
    resize(200, 200);
}

毎秒、QChronoTimerQWidget::update() スロットを呼び出し、時計の表示を更新します。

本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。