Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用PySide和多处理的GUI冻结_Python_Pyqt_Multiprocessing_Pyside - Fatal编程技术网

Python 使用PySide和多处理的GUI冻结

Python 使用PySide和多处理的GUI冻结,python,pyqt,multiprocessing,pyside,Python,Pyqt,Multiprocessing,Pyside,我正试图将繁重的后台工作转移到多处理过程中。我只希望单独的进程能够向我的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

我正试图将繁重的后台工作转移到
多处理过程中。我只希望单独的进程能够向我的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已停止工作。。。
有什么线索吗?原因是什么?。我自己想不出来。谢谢

您不应该在QThread的“run”方法中创建对象,从“run”发出信号,在这个函数中实现一个函数,比如“callerFunction”create object,最后根据“run”函数发出的信号调用这个函数

  • 您可以在已经创建的while循环中发出信号
  • 看看解决方案
  • 不要创建python进程,QThread足以完成此任务

很抱歉,您没有说明gui冻结的原因。但我会在有机会的时候检查你提供的链接。对不起,你所指的例子太愚蠢了。我没有安装PyQt,但我不认为将运行线程的线从类内移动到类外会有任何魔力。很抱歉,最近我总是按照我告诉你的那样做,而且对我来说总是很好。我想我有一个工作示例,请参阅我的帖子:我感谢你的关注,但这并不能回答问题,为什么有些时候它会工作,有些时候会崩溃?