我需要实现以下 UI: - 有一个带有“运行实验 1/X”标签的窗口和一个按钮 - 加载窗口时,会启动一些实验。实验由os.system
of运行subprocess.Popen
,它们只是预编译的 C++ 程序 - 实验应该严格地一个接一个地运行,而不是同时运行(因此我不能使用subprocess.Popen
) - 实验运行时窗口应该是活动的,用户可以按下按钮 - 按下按钮时,实验停止(我们可以等到当前实验结束并停止)并且窗口关闭 - 当所有实验结束时,窗口应自行关闭
首先我尝试在 中运行实验threading.Thread
,但它仍然挡住了窗口。所以我切换到multiprocessing.Process
:
class StoppableProcess(Process):
def __init__(self, name, alg, proj, parent):
Process.__init__(self)
self.stop = False
self.name = name
self.alg = alg
self.proj = proj
self.parent = parent
def stop(self):
self.stop = True
def stopped(self):
return self.stop
def run(self):
count = len([k for k in self.proj.values()])
i = 1
for p in self.proj.values():
self.parent.label.setText("Running experiment " + str(i) + " / " + str(count))
os.system("some command here")
i += 1
if self.stopped():
break
self.parent.hide()
class Runner(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.layout = QVBoxLayout()
self.label = QLabel("Running experiment 0 / 0")
self.setWindowTitle("Running experiments")
button = QPushButton("Break experiments")
self.layout.addWidget(self.label)
self.layout.addWidget(button)
self.setLayout(self.layout)
QObject.connect(button, SIGNAL("clicked()"), self.Break)
def Run(self, name, alg, proj):
self.thread = StoppableProcess(name, alg, proj, self)
self.thread.start()
self.show()
self.thread.join()
def Break(self):
self.thread.stop()
self.hide()
但是,这根本不起作用,显然是因为Runner
对象应该被腌制以传递给子进程,但是腌制失败了。我正在考虑避免传递父参数并改用 Qt 信号,但也许有更好的解决方案?