多处理和GUI更新-Qprocess还是多处理? [英] multiprocessing and GUI updating - Qprocess or multiprocessing?

查看:78
本文介绍了多处理和GUI更新-Qprocess还是多处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读了有关QProcesses和python的多处理模块的文献之后,我仍然难以在后台运行大型进程的情况下创建有效且响应迅速的GUI. 到目前为止,我已经提出了这个应用程序的简化版本,它仍然显示出与许多人所描述的问题类似的问题.

After reading the literature on QProcesses and the multiprocessing module for python, I am still having trouble creating a working and responsive GUI throughout having large processes ongoing in the background. So far, I have come up with this simplified version of my application, which still shows similar problems to what many have described.

from PyQt4 import QtCore, QtGui
import multiprocessing as mp
import numpy as np
import sys
class Spectra:
    def __init__(self, spectra_name, X, Y):
        self.spectra_name = spectra_name
        self.X = X
        self.Y = Y
        self.iteration = 0

    def complex_processing_on_spectra(self, pipe_conn):
        self.iteration += 1
        pipe_conn.send(self.iteration)

class Spectra_Tab(QtGui.QTabWidget):
    def __init__(self, parent, spectra):
        self.parent = parent
        self.spectra = spectra
        QtGui.QTabWidget.__init__(self, parent)

        self.treeWidget = QtGui.QTreeWidget(self)
        self.properties = QtGui.QTreeWidgetItem(self.treeWidget, ["Properties"])
        self.step = QtGui.QTreeWidgetItem(self.properties, ["Iteration #"])

        self.consumer, self.producer = mp.Pipe()
        # Make process associated with tab
        self.process = mp.Process(target=self.spectra.complex_processing_on_spectra, args=(self.producer,))

    def update_GUI(self, iteration):
        self.step.setText(1, str(iteration))

    def start_computation(self):
        self.process.start()
        while(True):
            message = self.consumer.recv()
            if message == 'done':
                break
            self.update_GUI(message)
        self.process.join()
        return

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self)

        self.setTabShape(QtGui.QTabWidget.Rounded)
        self.centralwidget = QtGui.QWidget(self)
        self.top_level_layout = QtGui.QGridLayout(self.centralwidget)

        self.tabWidget = QtGui.QTabWidget(self.centralwidget)
        self.top_level_layout.addWidget(self.tabWidget, 1, 0, 25, 25)

        process_button = QtGui.QPushButton("Process")
        self.top_level_layout.addWidget(process_button, 0, 1)
        QtCore.QObject.connect(process_button, QtCore.SIGNAL("clicked()"), self.process)

        self.setCentralWidget(self.centralwidget)
        self.centralwidget.setLayout(self.top_level_layout)

        # Open several files in loop from button - simplifed to one here
        X = np.arange(0.1200,.2)
        Y = np.arange(0.1200,.2)
        self.spectra = Spectra('name', X, Y)
        self.spectra_tab = Spectra_Tab(self.tabWidget, self.spectra)
        self.tabWidget.addTab(self.spectra_tab, 'name')

    def process(self):
        self.spectra_tab.start_computation()
        return

if __name__ == "__main__":
    app = QtGui.QApplication([])
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

如果有依赖项,这应该完全能够执行. 目前,我的程序有一个QThreaded版本,可以处理信号和插槽.但是,我认为具有使用所有计算机处理器的能力很重要,因为大多数用户可以使用约8个内核.因此,我想使用multiprocessingQProcess es将此信号/插槽线程化方法扩展到多处理版本.
是否有人建议使用QProcessmultiprocessing?虽然它们对我来说都很复杂,但是QProcess似乎使用pyQt的人论坛较少,所以我采用了多处理.因为我已经有使用线程的信号/插槽,使用QProcess会更简单吗?

This should be fully capable of executing if you have the dependencies. At the moment I have a QThreaded version of my program which works with signals and slots; Hwoever, I think it is important to have the ability to use all of a computers processors, since most users have ~8 cores available to them. So, I would like to expand this signal/slot threaded approach to the multiprocessed version using multiprocessing or QProcesses.
Does anyone have suggestions for whether or not to use QProcess or multiprocessing? While they are both complicated to me, QProcess seems as though it has less forums of people using pyQt, So I went with multiprocessing. Would it be simpler to go with QProcess since I already have signals/slots working with threads?

我是否应该按照建议添加这样的类?

Should I add a class like this as suggested?

class My_Process(QtCore.QProcess):
    def __init__(self, spectra):
        QtCore.QProcess.__init__(self)
        self.spectra = spectra

    def worker(self):
        QtConcurrent.run(self.spectra, self.spectra.complex_processing_on_spectra)

    def run(self):
        QtCore.QObject.connect(self, QtCore.SIGNAL(QTimer.timeout()), self.worker)

推荐答案

QProcess用于读取和写入管道(shell/cmd).使用其中之一.

QProcess is for reading and writing to pipes (shell/cmd). Use one of these.

  1. 使用辅助函数创建一个类,并通过QtConcurrent.run(object, method, args)
  2. 将其作为线程运行
  3. QTimer.timeout()与您的辅助函数连接.
  1. Create a class with worker function and run it as thread by QtConcurrent.run(object, method, args)
  2. connect QTimer.timeout() with your worker function.

这篇关于多处理和GUI更新-Qprocess还是多处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆