QtPyでQThreadを使う例
概要
QtPyでQThreadを使う例です.
QtPyについて
つくったもの
ボタンを押すとバックグラウンドで何かが実行される. 処理の進捗や終了したタイミングSignalとしてGUI側に送信される. このアプリケーションではやっていないが処理結果の値を終了時に送信することもできる.
コード
# -*- coding: utf-8 -*- import sys from qtpy.QtWidgets import ( QMainWindow, QApplication, QLabel, QWidget, QPushButton, QVBoxLayout ) from qtpy.QtCore import QObject, Qt, QThread, QMutex, QMutexLocker from qtpy.QtCore import Signal, Slot class ExampleWorker(QThread): updated = Signal(str) finished = Signal() def __init__(self, **kwargs): super(ExampleWorker, self).__init__(**kwargs) self.mutex = QMutex() self.stopped = False def __del__(self): self.stop() def start(self): super(ExampleWorker, self).start() self.stopped = False def stop(self): with QMutexLocker(self.mutex): self.stopped = True def run(self): import time # --------- めっちゃ重たい処理 --------- cnt = 0 while cnt < 20 and not self.stopped: self.updated.emit(str(cnt)) cnt = cnt + 1 time.sleep(0.25) # -------------------------------------- self.finished.emit() class MainWindow(QMainWindow): def __init__(self, **kwargs): super(MainWindow, self).__init__(**kwargs) # スレッドの準備 self.worker = ExampleWorker() self.worker.updated.connect(self.on_worker_updated) self.worker.finished.connect(self.on_worker_finished) # UIの準備 self.main_widget = QWidget(self) self.start_button = QPushButton('Start') self.start_button.clicked.connect(self.on_start_button_clicked) self.stop_button = QPushButton('Stop') self.stop_button.clicked.connect(self.on_stop_button_clicked) layout = QVBoxLayout() layout.addWidget(self.start_button) layout.addWidget(self.stop_button) self.main_widget.setLayout(layout) self.setCentralWidget(self.main_widget) self.resize(640, 480) def on_start_button_clicked(self): # スレッドが動いていないなら起動 if not self.worker.isRunning(): self.worker.start() def on_stop_button_clicked(self): self.worker.stop() @Slot(str) def on_worker_updated(self, s): print(s) @Slot() def on_worker_finished(self): print('おわり') def main(): app = QApplication(sys.argv) view = MainWindow() view.show() sys.exit(app.exec_()) if __name__ == '__main__': main()