这是我基于 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 次。它似乎从来没有给主线程时间,并且小部件没有响应。我是否在做一些阻止真正线程实际工作的事情?
(我使用的是 python 2.7 和 pyside 1.10。)
更新
如果我修改run
为直接完成工作,而不是基于QTimer
线程似乎可以正常工作。即更改run
为:
def run(self):
self.doWork()
return
这并不能解决我的问题,因为我想使用事件队列运行。因此,我怀疑这是某种信号/插槽问题,其中QTimer
信号与错误的线程相关联。
请注意,在工作完成之前,我不会体验exit
或阻止。quit
我只是遇到线程根本不起作用。即主窗口被阻止,我什至无法单击按钮甚至启动退出线程