\ 迷ったらまずTechAcademyの無料カウンセリング! /
PySide超入門【第22回 | 応用編】時計・カウンター・プログレスバーを作ろう!QTimer徹底解説

GUIアプリケーションを作るときに「一定間隔で処理を実行したい」「自動的に画面を更新したい」という場面はよくあります。
例えば「時計アプリで1秒ごとに時間を更新する」「ゲームでキャラクターを動かす」「センサー値を定期的に取得する」などです。
そんなときに活躍するのが QTimer クラスです。
QTimerは指定した間隔でシグナル(timeout
)を発行することで、イベントループに非同期的な処理を追加する仕組みを提供します。
今回の記事では QTimerの基本コードから、主要プロパティ・メソッドの解説、よくある質問まで まとめていきます。
QTimerとは?
QTimerは「一定間隔ごとに処理を実行する仕組み」を提供するクラスです。
基本コード
このサンプルコードでは、QTimer(タイマー機能)を使ってできることを3つまとめて紹介しています。
- ⏰ 時計 … 今の時刻を1秒ごとに表示します。
- 🔢 カウンター … 数字をカウントアップしていきます。
- 📊 プログレスバー … バーを少しずつ動かして「進み具合」を見せます。
それぞれの機能は別々の関数に分けて書いているので、どこを直せばいいのかがすぐに分かります。
「時計だけ使いたい!」という場合も、このコードをベースにすればすぐに自分のアプリに取り入れられます
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import (
QApplication, QWidget, QLabel, QVBoxLayout, QProgressBar, QHBoxLayout
)
import sys, datetime
class TimerDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QTimerデモ: 時計・カウンター・プログレスバー")
self.resize(400, 200)
# メインレイアウト
layout = QVBoxLayout(self)
# 時計エリア
self.clock_label = QLabel("時計: --:--:--")
layout.addWidget(self.create_clock_widget())
# カウンターエリア
self.counter_label = QLabel("カウンター: 0")
layout.addWidget(self.create_counter_widget())
# プログレスバーエリア
self.progress = QProgressBar()
layout.addWidget(self.create_progress_widget())
# 各機能を開始
self.start_clock()
self.start_counter()
self.start_progress()
# ---------- 時計 ----------
def create_clock_widget(self):
w = QWidget()
box = QHBoxLayout(w)
box.addWidget(self.clock_label)
return w
def start_clock(self):
self.clock_timer = QTimer()
self.clock_timer.timeout.connect(self.update_clock)
self.clock_timer.start(1000)
def update_clock(self):
self.clock_label.setText(
"時計: " + datetime.datetime.now().strftime("%H:%M:%S")
)
# ---------- カウンター ----------
def create_counter_widget(self):
w = QWidget()
box = QHBoxLayout(w)
box.addWidget(self.counter_label)
return w
def start_counter(self):
self.count = 0
self.counter_timer = QTimer()
self.counter_timer.timeout.connect(self.update_counter)
self.counter_timer.start(500)
def update_counter(self):
self.count += 1
self.counter_label.setText(f"カウンター: {self.count}")
# ---------- プログレスバー ----------
def create_progress_widget(self):
w = QWidget()
box = QHBoxLayout(w)
box.addWidget(self.progress)
return w
def start_progress(self):
self.value = 0
self.progress_timer = QTimer()
self.progress_timer.timeout.connect(self.update_progress)
self.progress_timer.start(100)
def update_progress(self):
self.value += 1
if self.value > 100:
self.progress_timer.stop()
self.progress.setValue(self.value)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = TimerDemo()
window.show()
sys.exit(app.exec())

主なプロパティとメソッド一覧(全解説)
No | メソッド / プロパティ | 説明 | 例 |
---|---|---|---|
1 | setInterval(int msec) | 繰り返し間隔を設定します。 | timer.setInterval(2000) |
2 | timeout (シグナル) | 設定時間ごとに発火するシグナル。 | timer.timeout.connect(func) |
3 | start(int msec) | タイマーを開始します。msecはミリ秒単位。 | timer.start(1000) |
4 | stop() | タイマーを停止します。 | timer.stop() |
5 | isActive() | タイマーが動作中か判定します。 | print(timer.isActive()) |
6 | remainingTime() | 次の timeout までの残り時間を取得します。 | print(timer.remainingTime()) |
7 | setSingleShot(bool) / isSingleShot() | 一度だけ発火する設定にする/設定を確認する。 | timer.setSingleShot(True) print(timer.isSingleShot()) |
8 | interval() | 現在の間隔(ミリ秒)を取得します。 | print(timer.interval()) |
9 | timerId() | 内部タイマーIDを返します | print(timer.timerId()) |
10 | QTimer.singleShot(int, callable) | 1回だけ処理を遅延実行する便利メソッド。 | QTimer.singleShot(3000, func) |
各プロパティ・メソッド 詳細解説
【1】タイマーの発火間隔を設定
概要:タイマーの発火間隔をミリ秒単位で設定します。
メソッド:setInterval(ms)
使い方(時計で使用):
def start_clock(self):
self.clock_timer.setInterval(2000) # 2秒ごとにtimeoutが発火
self.clock_timer.start()
【2】シグナル
概要:設定した間隔ごとに発火し、登録された関数を実行します。
シグナル:timeout
使い方(時計・カウンター・プログレスバーで共通):
self.clock_timer.timeout.connect(self.update_clock)
self.counter_timer.timeout.connect(self.update_counter)
self.progress_timer.timeout.connect(self.update_progress)
【3】タイマーを開始
概要:タイマーを開始します。引数を指定すると、その場で間隔を上書きできます。
メソッド:start()
使い方(カウンターで使用):
self.counter_timer.start()
【4】タイマーを停止
概要:タイマーを停止します。
メソッド:stop()
使い方(プログレスバーで使用):
def update_progress(self):
if self.value > 100:
self.progress_timer.stop()
【5】タイマーが動いているかどうか
概要:タイマーが現在動いているかどうかを確認します。
メソッド:isActive()
使い方(応用例):
if self.counter_timer.isActive():
print("カウンターは動作中です")
# カウンターは動作中です
# カウンターは動作中です
# ・・・
【6】次までの残り時間
概要:次に timeout
が発火するまでの残り時間(ミリ秒)を返します。
メソッド:remainingTime()
使い方(応用例):
print(self.progress_timer.remainingTime())
# 100
# 99
【7】ワンショットタイマーに設定
概要:一度だけ発火する「ワンショットタイマー」に設定できます。
メソッド:setSingleShot(True)
使い方(応用例):
def start_clock(self):
self.clock_timer.setSingleShot(True)
self.clock_timer.start(1000)
【8】タイマー間隔
概要:現在のタイマー間隔(ミリ秒)を取得します。
メソッド:interval()
使い方(応用例):
print(self.clock_timer.interval())
# 2000
【9】タイマーの内部ID
概要:タイマーの内部ID(整数値)を返します。
メソッド:timerId()
使い方(応用例):
print(f'時計タイマー:{self.clock_timer.timerId()}')
print(f'カウンタータイマー:{self.counter_timer.timerId()}')
print(f'プログレスタイマー:{self.progress_timer.timerId()}')
# 時計タイマー:1
# カウンタータイマー:2
# プログレスタイマー:3
【10】ワンショットタイマーの作成
概要:指定した時間後に一度だけ関数を呼び出す「ワンショットタイマー」を作ります。
静的メソッド:QTimer.singleShot(ms, function)
使い方(応用例):
def __init__(self):
QTimer.singleShot(3000, lambda: print("3秒後に実行!"))
# 3秒後に実行!
よくある質問(FAQ)
sleep()
を使ったらGUIが止まってしまいました。なぜ?-
sleep()
はイベントループをブロックするため、GUIがフリーズします。代わりにQTimer
を使いましょう。 - 複数のQTimerを同時に動かせますか?
-
はい。独立したQTimerを作成すれば、それぞれが並行して動作します。
- 一度だけ処理を遅延実行したい場合はどうすればいい?
-
QTimer.singleShot(ms, func)
を使うのが便利です。 - 精度は高いですか?
-
高精度ではありません。OSのイベントループに依存するため、数ms〜数十msの誤差が出る場合があります。
- アニメーションとQTimerはどちらを使うべきですか?
-
単純に一定間隔で処理したいならQTimer、滑らかな動きを作りたいならQPropertyAnimationやQTimeLineが適しています。
まとめ
QTimer
は、一定の間隔ごとに自動で処理を実行できる 非同期タイマー です。これを使うことで、GUIアプリケーションが止まることなく、時間に応じた処理を簡単に組み込むことができます。
基本的な使い方は、start(msec)
でタイマーを開始し、timeout.connect(...)
で処理したい関数を接続する方法です。例えば、1秒ごとに画面を更新したり、カウンターを進めたりする処理を簡単に実装できます。
また、setSingleShot(True)
や QTimer.singleShot(...)
を使えば、一度だけ実行したい処理も簡単に書けます。例えば、アプリ起動後に1回だけメッセージを表示する、といった場面で便利です。
GUIアプリを作る上で、ユーザー操作をブロックせずに時間に応じた処理を行うには、QTimer
の理解と活用が欠かせません。非同期処理の基礎として、ぜひ使いこなせるようにしましょう。
コメント