在后台执行可能更长的线程时,为了不锁定GUI,我对QThread进行了控制。我试着练习写一个简单的应用程序:一个倒计时计时器,我可以通过点击“开始”按钮启动,从而启动倒计时循环,我可以通过单击“暂停”按钮暂停。在
我想用QThread(解释了over here)的“正确方式”来实现,即子类化QObject,然后通过moveToThread将这个子类的一个实例附加到QThread。我用QTDesigner做了GUI,这是到目前为止我在Python中修改的内容(来自网络上的其他示例):
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QThread, SIGNAL
import time, sys, mydesign
class SomeObject(QtCore.QObject):
def __init__(self, lcd):
super(self.__class__, self).__init__()
self.lcd = lcd
self.looping = True
finished = QtCore.pyqtSignal()
def pauseLoop(self):
print "Hello?"
self.looping = False
def longRunning(self):
count = 10
self.lcd.display(count)
while count > 0 and self.looping:
time.sleep(1)
count -= 1
self.lcd.display(count)
self.finished.emit()
class ThreadingTutorial(QtGui.QMainWindow, mydesign.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
#an instance of SomeObject gets attached to
#an instance of wrapper class QThread()
#objThread is a wrapper object for an instance of
# self-defined class SomeObject
self.objThread = QtCore.QThread()
self.obj = SomeObject(self.lcdNumber)
self.obj.moveToThread(self.objThread)
#connect all the signals
self.obj.finished.connect(self.objThread.quit)
self.objThread.started.connect(self.obj.longRunning)
self.startCountdown.clicked.connect(self.objThread.start)
self.pauseButton.clicked.connect(self.obj.pauseLoop)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
form = ThreadingTutorial()
form.show()
app.exec_()
GUI没有被锁定,但是pauseLoop()函数只在循环完成后执行。如何才能实现在longRunning()中暂停循环的目标?在
提前通知!在
更新:
在Steve和three_npenapples的评论的帮助下,我使用objThread的内部事件循环提出了以下解决方案:
^{pr2}$
之所以发生这种情况,是因为您告诉Qt在一个线程中运行}必须在
SomeObject
对象的代码。在代码中,有两个线程,主GUI线程和self.objThread
。在与longRunning()
相同的线程中调用pauseLoop()
,这意味着{pauseLoop()
运行之前完成。相反,您需要从另一个线程调用pauseLoop()
,而不是self.objThread
。在请注意,当您开始更改来自两个不同线程(主线程和新线程)的数据时,您可能会开始遇到争用条件。既然你只设置了一个布尔变量,你会很好,但这是需要记住的。在
编辑:正如
three_pineapples
的评论所指出的,访问GUI对象(例如:QWidget
)应该只在主GUI线程中完成。为了说明这是如何工作的,我更新了这个答案,以使用信号更新GUI线程中的LCD,而不是仅仅将值打印到stdout。我还添加了一些代码来打印不同部分的当前线程。在输出示例:
^{pr2}$相关问题 更多 >
编程相关推荐