如何在子进程期间和之后执行操作

2024-06-17 13:41:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个调用子程序的程序。当子程序与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。我在程序中添加了以下代码:

^{pr2}$

输出如下:

点击“运行”(子程序运行完成后输出)

Finish running

第二次单击“运行”

Started

点击“停止”

Finish running
Finish running

第三次单击“运行”

Started
Started

点击“停止”

Finish running
Finish running
Finish running

这里出了点事。在


Tags: runself程序def按钮runningstoppopen
1条回答
网友
1楼 · 发布于 2024-06-17 13:41:06

p = subprocess.Popen(exe)不等待exe完成,只要exe启动,它就会返回。在

p.communicate()确实在等待子进程结束,因此它会阻塞您的GUI线程(GUI冻结,直到子进程退出)。在

为了避免阻塞GUI,您可以检查p.poll()是否返回{},以确定{}进程是否仍在运行。通常GUI框架提供了一种设置周期性回调(例如Qt的QTimer)的方法,您可以在那里调用p.poll()。 或者将阻塞调用(例如p.wait())放入后台线程,并在完成时通知GUI线程(发出信号,生成事件)。在

QProcesssuggested by @dano已经有了内置的通知机制(finished信号)。在

As @three_pineapples said:如果不想多次调用回调,请不要多次连接同一信号。在您的案例中,对同一流程实例多次调用.start()是没有意义的:

def run(self):
    self.runButton.setEnabled(False) # call it first because 
                                     # processes are not started instantly
    self.process = QtCore.QProcess(self) 
    self.process.started.connect(self.onstart) # connect "start" signal
    self.process.finished.connect(self.onfinish)
    self.process.start(exe_path, args) # then start

相关问题 更多 >