下面的代码创建一个带有标签和按钮的对话框。
按下按钮可调用onClick
函数,该函数将calculate
作为任务放入queue
触发thread
来完成工作。
线程完成后,我想调用dialog.onThreadCompleted
方法将计算结果作为参数传递给它。然后,此方法将使用self.label
执行的计算结果更新thread
。如何实现呢?
import threading
import Queue as Queue
import functools
global queue
queue = Queue.Queue()
class Thread(QThread):
def __init__(self, parent=None):
QThread.__init__(self, parent)
def run(self):
global queue
while True:
partial = queue.get()
output = partial()
queue.task_done()
threads = []
thread = Thread()
threads.append(thread)
thread.start()
def calculate(number):
for i in range(number):
i += i
print 'calculate completed. result: %s' % i
return i
class Dialog(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setLayout(QVBoxLayout())
self.label = QLabel(self)
self.label.setText('This label should display result')
self.layout().addWidget(self.label)
button = QPushButton('Start process')
button.clicked.connect(self.onClick)
self.layout().addWidget(button)
def onThreadCompleted(self, result):
self.label.setText(str(result))
def onClick(self):
self.label.setText('Calculation is starting...')
partial = functools.partial(calculate, number=100000000)
queue.put(partial)
if __name__ == '__main__':
app = QApplication([])
dialog = Dialog()
dialog.show()
qApp.exec_()
答案 0 :(得分:1)
我决定修改您的代码,以便仅使用PyQt
(无Queue
或Thread
,仅使用QThread
)。我希望代码是自我解释的。如果没有,请问:)
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QDialog
from PyQt4.QtGui import *
import sys
class Thread(QtCore.QObject):
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
QtCore.QObject.__init__(self, parent)
self.TheWorker = QtCore.QThread()
self.moveToThread(self.TheWorker)
self.TheWorker.start()
self.number = 0
def calculate(self):
num = 10000
for i in range(num):
self.number += i
print 'calculate completed. result: %s' % self.number
self.finished.emit()
class Dialog(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
# worker which will do the job or you on different thread
self.myWorker = Thread()
# catched signal about finishing the job and calls desired method
self.myWorker.finished.connect(self.onThreadCompleted)
self.setLayout(QVBoxLayout())
self.label = QLabel(self)
self.label.setText('This label should display result')
self.layout().addWidget(self.label)
button = QPushButton('Start process')
button.clicked.connect(self.myWorker.calculate)
self.layout().addWidget(button)
def onThreadCompleted(self):
self.label.setText(str(self.myWorker.number))
# to quit the thread properly
def quitThread(self):
self.myWorker.TheWorker.quit()
self.myWorker.TheWorker.wait()
if __name__ == '__main__':
app = QApplication([])
dialog = Dialog()
dialog.show()
qApp.exec_()
dialog.quitThread()
sys.exit()