我有一个调用子程序的程序。当子程序与Popen一起运行时,我需要禁用run按钮和启用stop按钮。但是,因为Popen打开了一个新的进程,在程序完成后应该打印的内容将立即打印出来。我尝试在Popen
之后添加self.p.communicate()
,但是GUI将冻结,直到子程序完成运行,因此stop按钮不起作用。
这是我的计划:
def gui(QtGui.QWidget):
...
self.runButton = QtGui.QPushButton('Run')
self.stopButton = QtGui.QPushButton('Stop')
self.runButton.clicked.connect(self.run)
self.stopButton.clicked.connect(self.kill)
self.runButton.setEnabled(True)
self.stopButton.setEnabled(False)
def run(self):
self.runButton.setEnabled(False)
self.p = subprocess.Popen(sample.exe)
#self.p.communicate()
self.stopButton.setEnabled(True)
print "Finish running" #without communicate() it will print out before .exe finish running
def kill(self):
self.p.kill()
self.stopButton.setEnabled(False)
print 'You have stop the program'
self.runButton.setEnabled(True)
我使用的是Window7、python2.7、pyqt4。我不必使用子程序,任何打开并能杀死子程序的都可以。在
提前谢谢。在
编辑:按照dano的建议尝试使用QProcess
。我在程序中添加了以下代码:
输出如下:
点击“运行”(子程序运行完成后输出)
Finish running
第二次单击“运行”
Started
点击“停止”
Finish running
Finish running
第三次单击“运行”
Started
Started
点击“停止”
Finish running
Finish running
Finish running
这里出了点事。在
p = subprocess.Popen(exe)
不等待exe
完成,只要exe
启动,它就会返回。在p.communicate()
确实在等待子进程结束,因此它会阻塞您的GUI线程(GUI冻结,直到子进程退出)。在为了避免阻塞GUI,您可以检查},以确定{}进程是否仍在运行。通常GUI框架提供了一种设置周期性回调(例如Qt的QTimer)的方法,您可以在那里调用
p.poll()
是否返回{p.poll()
。 或者将阻塞调用(例如p.wait()
)放入后台线程,并在完成时通知GUI线程(发出信号,生成事件)。在QProcesssuggested by @dano已经有了内置的通知机制(
finished
信号)。在As @three_pineapples said:如果不想多次调用回调,请不要多次连接同一信号。在您的案例中,对同一流程实例多次调用
.start()
是没有意义的:相关问题 更多 >
编程相关推荐