Skip to main content
 首页 » 编程设计

python之使用 PySide 和多处理卡住 GUI

2024年11月01日4kuangbin

我正在尝试将繁重的后台作业卸载到 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 作为参数传递给进程,因为那不是 pickleable:

#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 足以完成这项工作