使用PySide进行GUI冻结和多处理

时间:2013-09-27 05:43:11

标签: python pyqt multiprocessing pyside

我正在尝试将繁重的后台作业卸载到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已停止工作... 有什么理由是什么原因?我自己无法弄明白。感谢

1 个答案:

答案 0 :(得分:2)

你不应该在QThread的“run”方法中创建对象,从“run”发出信号,在这个函数中实现一个函数说“callerFunction”创建对象,最后在由此函数发出的信号上调用此函数“跑”功能。

  • 您可以在已创建的while循环中发出信号。
  • 查看this解决方案
  • 不创建python进程,QThread足以完成这项工作