次の UI を実装する必要があります。 - 「実行中の実験 1/X」というラベルの付いたウィンドウとボタンがあります。 - ウィンドウが読み込まれると、いくつかの実験が開始されます。実験は によって実行されos.system
、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 シグナルを使用することを考えていましたが、もっと良い解決策があるのでしょうか?