Qtフレームワークを利用したアプリケーション開発において、特定の処理を一定時間ごとに自動実行させたい場面は少なくありません。例えば、データのポーリング、UIの更新、バックグラウンドでの状態チェックなどがこれに該当します。Qtでは、このような定期的なタスクのスケジューリングをQTimerクラスを使って簡単かつ効率的に実装することができます。
QTimerの基本
QTimerは、指定された時間が経過するたびにシグナルを発行するオブジェクトです。このシグナルをカスタムスロットに接続することで、アプリケーションはイベントループ内で安全に定期処理を実行できます。
- インターバル設定:
setInterval()メソッドで、タイマーがシグナルを発行する間隔(ミリ秒単位)を設定します。 - シグナルとスロット: タイマーは
timeout()シグナルを発行します。このシグナルを処理したいスロットに接続します。 - タイマー開始・停止:
start()メソッドでタイマーを開始し、stop()メソッドで停止します。
実装例: 一定間隔でのログ出力
以下に、QTimerを使用して1秒ごとにデバッグログを出力する簡単なQtアプリケーションの例を示します。この例では、メインウィンドウクラスにタイマーを組み込みます。
ヘッダーファイル (例: mainwindow.h)
メインウィンドウクラスにQTimerのインスタンスと、タイマーイベントを処理するスロット、そして実行回数を記録するプライベートメンバーを追加します。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer> // QTimerを使用するためにインクルード
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void handleScheduledEvent(); // タイマーイベントを処理するスロット
private:
Ui::MainWindow *ui;
QTimer *m_eventScheduler; // QTimerインスタンス
int m_executionCount; // 実行回数をカウント
};
#endif // MAINWINDOW_H
ソースファイル (例: mainwindow.cpp)
コンストラクタ内でQTimerを初期化し、インターバルを設定、そしてtimeout()シグナルをカスタムスロットに接続します。最後にstart()メソッドでタイマーを開始します。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug> // デバッグ出力用
#include <QDateTime> // タイムスタンプ表示用
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_executionCount(0) // カウンターを初期化
{
ui->setupUi(this);
// QTimerインスタンスの作成
m_eventScheduler = new QTimer(this);
// タイマーのインターバルを設定(例: 1000ミリ秒 = 1秒)
m_eventScheduler->setInterval(1000);
// timeoutシグナルをスロットに接続
connect(m_eventScheduler, &QTimer::timeout, this, &MainWindow::handleScheduledEvent);
// タイマーを開始
m_eventScheduler->start();
qDebug() << "QTimer started. Executing every" << m_eventScheduler->interval() << "ms.";
}
MainWindow::~MainWindow()
{
delete ui;
// QTimerは親オブジェクトが破棄されるときに自動的に解放されるため、
// ここでdeleteする必要はありませんが、明示的に記述することも可能です。
// delete m_eventScheduler;
}
// スケジュールされたイベントを処理するスロット
void MainWindow::handleScheduledEvent()
{
m_executionCount++; // 実行回数をインクリメント
qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
<< QString(" - 周期イベント実行 (%1回目)").arg(m_executionCount);
// ここに定期的に実行したい処理を記述します。
// 例: データの更新、センサー値の読み取り、UIの再描画など
}
解説
上記のコードは、以下の手順で定期実行を実現しています。
MainWindowクラスのプライベートメンバーとしてQTimer *m_eventScheduler;を宣言し、コンストラクタでインスタンスを生成します。m_eventScheduler->setInterval(1000);で、タイマーが1000ミリ秒(1秒)ごとにtimeout()シグナルを発行するように設定します。connect(m_eventScheduler, &QTimer::timeout, this, &MainWindow::handleScheduledEvent);を使用して、タイマーのtimeout()シグナルが発せられたときに、MainWindowオブジェクトのhandleScheduledEvent()スロットが呼び出されるように接続します。m_eventScheduler->start();を呼び出すことで、タイマーが作動を開始します。handleScheduledEvent()スロット内で、m_executionCountをインクリメントし、現在時刻と実行回数をデバッグ出力しています。ここに、アプリケーションで定期的に行いたい任意の処理を実装します。
このように、QTimerを用いることで、Qtアプリケーション内で簡単に周期的なタスクを管理し、実行することができます。複数の異なるタイミングでタスクを実行したい場合は、複数のQTimerインスタンスを作成し、それぞれ独立して設定・管理することが可能です。