スレッドを使わずに定期的に GUI を更新するために、QTimer
の使い方と挙動について簡単に調べてみました。
環境
- Python 3.8.10
- PySide 6.2.2.1
サンプルコード
import sys
import time
from datetime import datetime
from PySide6.QtCore import (QTimer, Signal)
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QLabel)
class MainWindow(QWidget):
"""メインウィンドウ
"""
countup = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.__count = 0
layout = QVBoxLayout()
self.__label = QLabel(self.__current_count())
layout.addWidget(self.__label)
self.setLayout(layout)
self.__timer = QTimer(self)
self.__timer.timeout.connect(self.__timeout)
self.__timer.start(1000)
self.__timer.singleShot(10000, self.__single_shot1)
self.__timer.singleShot(15000, self.__single_shot2)
def __timeout(self):
self.__count += 1
print(f'{datetime.now()}, {self.__count}')
self.__label.setText(self.__current_count())
#time.sleep(3)
def __current_count(self) -> str:
return f'現在のカウント: {self.__count}'
def __single_shot1(self):
print(f'{datetime.now()}, 10秒経過')
def __single_shot2(self):
print(f'{datetime.now()}, 15秒経過')
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
ret = app.exec()
sys.exit(ret)
2023-03-27 14:04:40.166652, 1
2023-03-27 14:04:41.115886, 2
2023-03-27 14:04:42.066937, 3
2023-03-27 14:04:43.026873, 4
2023-03-27 14:04:44.026648, 5
2023-03-27 14:04:45.026877, 6
2023-03-27 14:04:46.026574, 7
2023-03-27 14:04:47.026898, 8
2023-03-27 14:04:48.026477, 9
2023-03-27 14:04:49.027008, 10秒経過
2023-03-27 14:04:49.027169, 10
2023-03-27 14:04:50.027045, 11
2023-03-27 14:04:51.026868, 12
2023-03-27 14:04:52.027034, 13
2023-03-27 14:04:53.026916, 14
2023-03-27 14:04:54.026824, 15秒経過
2023-03-27 14:04:54.027010, 15
処理に時間がかかった場合はどうなる?
上記のコードでは、1秒ごとに __timeout
関数が実行されますが、もしその中で処理に時間がかかったとしたらどうなるか?
試しに3秒のスリープを入れてみました(上記のコメントアウトを解除)。
2023-03-27 14:07:10.458991, 1
2023-03-27 14:07:13.462465, 2
2023-03-27 14:07:16.464238, 3
2023-03-27 14:07:19.467192, 4
2023-03-27 14:07:22.470589, 10秒経過
2023-03-27 14:07:22.471410, 5
2023-03-27 14:07:25.475184, 6
2023-03-27 14:07:28.478740, 15秒経過
2023-03-27 14:07:28.480526, 7
2023-03-27 14:07:31.484492, 8
3秒経過後、すぐに __timeout
がコールされています。
前の処理が完了しないと次の処理は行われないようです。