如何在我的 PyQt-GUI 上应用多处理模块



我知道这是一个老问题,并且已经在其他问题中找到了答案,例如这里的这个线程。但是,在我的情况下应用它时遇到了一些问题。

我现在的方式如下:我有我的 MainWindow 类,我可以在其中输入一些数据。然后我有一个Worker class,它是一个PySide2.QtCore.QThread对象。对于这个类,我从主窗口传递一些输入数据。在这个 Worker 类中,我有一个设置一些 Worker 类的方法,在 Worker 类的另一个方法中,这些常微分方程正在由 scipy.integrate.solve_ivp 解决。集成完成后,我通过信号将结果发送回主窗口。所以代码大致看起来像这样:

import PySide2
from scipy.integrate import solve_ivp
class Worker(QtCore.QThread):
def __init__(self,*args,**kwargs):
super(Worker,self).__init__()
"Here I collect input parameters"
def run(self):
"Here I call solve_ivp for the integration and send a signal with the 
solution when it is done"
def ode_fun(self,t,c):
"Function where the ode equations are set up"

class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
"set up the GUI"
self.btnStartSimulation.clicked.connect(self.start_simulation) #button to start the integration
def start_simulation(self):
self.watchthread(Worker)
self.thread.start()
def watchthread(self,worker):
self.thread = worker("input values")
"connect to signals from the thread"

现在我明白了,使用多处理模块,我应该能够在另一个处理器内核上集成运行线程,以使其更快并减少 GUI 滞后。但是,从上面的链接中,我不确定应该如何应用此模块,甚至不确定如何重组我的代码。我是否必须将我现在在 Worker 类中的代码放入另一个类中,或者我是否能够以某种方式在现有线程上应用多处理模块? 任何帮助将不胜感激!

编辑: 新代码如下所示:

class Worker(QtCore.QThread):
def __init__(self,*args,**kwargs):
super(Worker,self).__init__()
self.operation_parameters = args[0]
self.growth_parameters = args[1]
self.osmolality_parameters = args[2]
self.controller_parameters = args[3]
self.c_zero = args[4]
def run(self):
data = multiprocessing.Queue()
input_dict = {"function": self.ode_fun_vrabel_rushton_scaba_cont_co2_oxygen_biomass_metabol,
"time": [0, self.t_final],
"initial values": self.c_zero}
data.put(input_dict)
self.ode_process = multiprocessing.Process(target=self.multi_process_function, args=(data,))
self.ode_process.start()
self.solution = data.get()
def multi_process_function(self,data):
self.message_signal = True
input_dict = data.get()
solution = solve_ivp(input_dict["function"], input_dict["time"],
input_dict["initial values"], method="BDF")
data.put(solution)
def ode_fun(self,t,c):
"Function where the ode equations are set up"
(...) = self.operation_parameters
(...) = self.growth_parameters
(...) = self.osmolality_parameters
(...) = self.controller_parameters

如果我通过 self 访问 ode_fun 函数中的参数可以吗?parameter_name"?还是我还必须使用数据参数传递它们?
使用当前代码,我收到以下错误:类型错误:无法腌制工作线程对象

你可以像这样从你的worker调用它:

import PySide2
from scipy.integrate import solve_ivp
import multiprocessing
class Worker(QtCore.QThread):
def __init__(self,*args,**kwargs):
super(Worker, self).__init__()
self.ode_process = None
"Here I collect input parameters"
def run(self):
"Here I call solve_ivp for the integration and send a signal with the solution when it is done"
data = multiprocessing.Queue()
data.put("all objects needed in the process, i would suggest a single dict from which you extract all data")
self.ode_process = multiprocessing.Process(target="your heavy duty function", args=(data,))
self.ode_process.start()  # this is non blocking
# if you want it to block:
self.ode_process.join()
# make sure you remove all input data from the queue and fill it with the result, then to get it back:
results = data.get()
print(results)  # or do with it what you want to do...
def ode_fun(self, t, c):
"Function where the ode equations are set up"

class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
"set up the GUI"
self.btnStartSimulation.clicked.connect(self.start_simulation) #button to start the integration
def start_simulation(self):
self.watchthread(Worker)
self.thread.start()
def watchthread(self,worker):
self.thread = worker("input values")
"connect to signals from the thread"

还要注意,现在每次按下启动模拟时都会覆盖正在运行的进程。您可能希望为此使用某种锁。

最新更新