问题描述
阅读有关 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 个内核可供他们使用.因此,我想使用 multiprocessing
或 QProcess
es 将此信号/插槽线程方法扩展到多处理版本.
是否有人对是否使用 QProcess
或 multiprocessing
有建议?虽然它们对我来说都很复杂,但 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 QProcess
es.
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.
- 创建一个带有工作函数的类并通过
QtConcurrent.run(object, method, args)将其作为线程运行
- 将
QTimer.timeout()
与您的工作函数连接.
- Create a class with worker function and run it as thread by
QtConcurrent.run(object, method, args)
- connect
QTimer.timeout()
with your worker function.
这篇关于多处理和 GUI 更新 - Qprocess 还是多处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!