我正在尝试将繁重的后台作业卸载到 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
able:
#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 已停止工作... 任何线索是什么原因?我自己弄不明白。谢谢
请您参考如下方法:
你不应该在 QThread 的“运行”方法中创建对象,从“运行”发出信号,实现一个函数说“callerFunction”在这个函数中创建对象,最后调用这个函数发出的信号“运行”功能。
- 您可以在已经创建的 while 循环中发出信号。
- 看看this解决方案
- 不要创建 python 进程,QThread 足以完成这项工作