こんばんわ
仕様が無いのかよくわからないので質問します
やりたいこと
ロード画面を実現したいので、QThreadを使って実現しようとしました。
しかし、QThreadに重い処理を入れて稼動させるとMainThreadの動作(描画)が止まってしまい、実現しませんでした。
この問題を解決したいです。
環境
Python3.6
PyQt5
PyCharm
ソース
Python
1import sys 2from PyQt5.QtWidgets import QApplication, QProgressDialog 3from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot 4from PyQt5 import QtWidgets 5 6"""ロード用のスレッド""" 7class Worker(QObject): 8 once = pyqtSignal() 9 loop = pyqtSignal() 10 finished = pyqtSignal() 11 12 def __init__(self, name): 13 super(Worker, self).__init__() 14 self.name = name 15 self.end = False 16 17 def run(self): 18 print("[start]" + self.name) 19 self.once.emit() 20 while not self.end: 21 self.loop.emit() 22 if self.end: 23 break 24 QThread.sleep(2) 25 self.finished.emit() 26 print("[end]" + self.name) 27 28 @pyqtSlot() 29 def finish(self): 30 self.end = True 31 32 33"""ロード画面""" 34class Loading(QProgressDialog): 35 36 def __init__(self): 37 super(Loading, self).__init__() 38 self.setRange(0,0) 39 40 # 処理用 41 self.processth = QThread() 42 self.processworker = Worker("worker") 43 self.processworker.moveToThread(self.processth) 44 self.processworker.once.connect(self.loadProcess) 45 self.processworker.finished.connect(self.processworker.deleteLater) 46 self.processworker.finished.connect(self.endProcess) 47 self.processth.started.connect(self.processworker.run) 48 49 50 51 """ロード中に行う処理""" 52 def loadProcess(self): 53 #本来はこの部分に重い処理を入れます 54 QThread.sleep(5) #5秒待機 55 print("待機後") 56 57 58 """スレッドを開始します。""" 59 def startProcess(self): 60 self.processth.start() 61 62 def endProcess(self): 63 print("スレッドが終了しました。") 64 65if __name__ == "__main__": 66 print("start") 67 app = QApplication([]) 68 l = Loading() 69 l.setGeometry(300, 300, 100, 50) 70 l.show() 71 l.startProcess() 72 sys.exit(app.exec_())
※finishedまでたどり着かないのは気にしないでください。
実装方法はQObjectを継承したworkerを使って、moveToThreadでスレッドを入れるやり方です。
仮のプログレスバー画面を表示してから擬似的な重い処理として5秒のスリープを行うスレッドを稼動させています。
試したこと
「実はMainThread上で動いており、それが影響して描画が止まるのでは?」
そう思ったので、スレッド1の上にスレッド2を乗せて、スレッド1を常時更新できるようにしましたが、それでも描画が止まりました。
QApplication.processEventsも設置してみましたが、だめでした。
そもそもループ中ではなく、1つの重い処理を想定しているため何度も呼び出せるものではありません。
その他
Qthreadでは実現不可能なのでは?と少し疑っていたりします。
方法自体が間違ってるならそれでいいんですが・・・。
以上です、よろしくお願いします。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/31 05:19