我正在尝试将繁重的后台作业卸载到multiprocessing
进程。我只是希望单独的进程能够向GUI报告它的进度。这是我的最后一次尝试,GUI很简单,有几个按钮和一个进度条:
from PySide.QtGui import *
from PySide.QtCore import *
import sys
from multiprocessing import Process, Pipe
import time
class WorkerClass:
#This class has the job to run
def worker(self, pipe):
for i in range(101):
pipe.send(i)
time.sleep(.02)
class WorkStarter(QThread):
#this thread takes a widget and updates it using progress sent from
#process via Pipe
def __init__(self, progressBar):
super().__init__()
self.progress_bar = progressBar
def run(self):
worker_obj = WorkerClass()
myend, worker_end = Pipe(False)
self.p = Process(target=worker_obj.worker, args=(worker_end,))
self.p.start()
while True:
val = myend.recv()
self.progress_bar.setValue(val)
if val == 100:
break
class WorkingWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle('Blue collar widget')
layout = QHBoxLayout()
start_btn = QPushButton('Start working')
start_btn.clicked.connect(self.startWorking)
end_btn = QPushButton('End working')
end_btn.clicked.connect(self.endWorking)
layout.addWidget(start_btn)
layout.addWidget(end_btn)
self.progress_bar = QProgressBar()
layout.addWidget(self.progress_bar)
self.setLayout(layout)
def startWorking(self):
self.thread = WorkStarter(self.progress_bar)
self.thread.start()
def endWorking(self):
self.thread.terminate()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = WorkingWidget()
main.show()
sys.exit(app.exec_())
我无法将任何QObject
作为参数传递给流程,因为那不是pickle
能够:
#cannot do the following
...
def startWorking(self):
self.worker_obj = WorkerClass()
#pass the progress bar to the process and the process updates the bar
self.p = Process(target=self.worker_obj.worker, args=(self.progress_bar,))
问题是这个gui有时会起作用,有时会冻结(所以请多次按'开始'直到它冻结:)),在Windows上它说:pythonw.exe已停止工作... 有什么理由是什么原因?我自己无法弄明白。感谢
答案 0 :(得分:2)
你不应该在QThread的“run”方法中创建对象,从“run”发出信号,在这个函数中实现一个函数说“callerFunction”创建对象,最后在由此函数发出的信号上调用此函数“跑”功能。