これが私がQThreadに基づいて書いた私の素敵なスレッドです。イベントキューがあることに気付くでしょう。4秒後、イベントが発生し、でいくつかの作業が行われdoWork
ます。doWork
すべての印刷の間にスリープし、他のスレッドに実行の機会を与える必要があります。doWork
すべての印刷とスリープの実行が十分に長く、別のスレッドが実際に実行するのに時間がかかると言えば十分です。
from PySide.QtCore import *
from PySide.QtGui import *
class DoStuffPeriodically(QThread):
def __init__(self):
super(DoStuffPeriodically, self).__init__()
def doWork(self):
#... do work, post signal to consumer
print "Start work"
for i in range(0,100):
print "work %i" % i
QThread.msleep(10)
print "Done work"
return
def run(self):
""" Setup "pullFiles" to be called once a second"""
self.timer= QTimer()
self.timer.setSingleShot(True)
self.timer.timeout.connect(self.doWork)
self.timer.start(4000)
self.exec_()
これが私のスレッドを制御するために使用しているトップレベルのQTウィジェットです。基本的には、スレッドを開始/停止するプッシュボタンだけです。
class Widg(QWidget):
def __init__(self):
super(Widg, self).__init__()
self.thread = DoStuffPeriodically()
self.startStopButton = QPushButton()
hBoxLayout = QHBoxLayout()
hBoxLayout.addWidget(self.startStopButton)
self.startStopButton.pressed.connect(self.startStopThread)
self.setLayout(hBoxLayout)
self.threadRunning = False
def startStopThread(self):
if self.threadRunning:
print "Stopping..."
self.thread.exit(0)
self.threadRunning = False
print "Stopped"
else:
print "Starting..."
self.thread.start()
self.threadRunning = True
print "Started"
if __name__ == "__main__":
from sys import argv
qApp = QApplication(argv)
widg = Widg()
widg.show()
qApp.exec_()
startStopButtonをクリックすると、スレッドが印刷を開始するのを確認できます。
起動... 開始しました... 仕事を始める 仕事0 仕事1 ..。 仕事99 完了しました
しかし、私がやりたいのは、スレッドが動作している間、スレッドを停止できるようにすることです。私はの線に沿って何かを期待しています
起動... 開始しました... 仕事を始める 仕事0 仕事1 ..。 仕事N 停止しています... 仕事99 完了しました 停止...
代わりに、ワーカースレッドがメインスレッドの実行を妨げているように見えますか?そして、startStopButtonをクリックする前に、作業が完了するのを待つ必要があります。
起動... 開始しました... 仕事を始める 仕事0 仕事1 ..。 仕事99 完了しました 停止しています... 停止...
実行時間は関係ありませんdoWork
。私はそれを10000回ループするように上げました。メインスレッドに時間を戻すことはないようで、ウィジェットは応答しません。実際のスレッドが実際に機能するのを妨げるようなことをしていますか?
(私はpython2.7とpyside1.10を使用しています。)
アップデート
run
スレッドに基づいていない直接作業を行うように変更すると、QTimer
正しく機能しているように見えます。つまり、次のように変更run
します。
def run(self):
self.doWork()
return
イベントキューを使用して実行したいので、これでは問題は解決しません。QTimer
したがって、これは、信号が間違ったスレッドに関連付けられている、ある種の信号/スロットの問題であると思われます。
作業が完了するまで、私はそれを経験していないexit
か、ブロックしていないことに注意してください。quit
スレッドがまったく機能しないのを経験しているだけです。つまり、メインウィンドウがブロックされており、ボタンをクリックしてスレッドを終了することすらできません。