正如其他人所说,subprocess.call 将等到命令完成。
但鉴于您使用的是 PyQt,使用 QProcess 可能会更好,因为这将允许您使用信号和事件来保持 GUI 响应。
有几个问题需要考虑。
首先,如果输出文件已经存在,示例ffmpeg 命令将挂起,因为默认情况下,它会提示用户允许覆盖。所以最好添加-y 或-n 标志来处理这个问题。
其次,该命令也可能由于某些意外原因而挂起。所以你可能应该给用户一种强制终止进程的方法。
最后,如果用户试图在命令完成之前关闭应用程序会发生什么?可能你需要处理主窗口的closeEvent 来处理它。
下面的演示脚本显示了处理上述问题的一些可能方法:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QVBoxLayout(self)
self.label = QtGui.QLabel('Elapsed: 0', self)
layout.addWidget(self.label)
self.buttonStart = QtGui.QPushButton('Start', self)
self.buttonStart.clicked.connect(self.handleButtonStart)
layout.addWidget(self.buttonStart)
self.buttonStop = QtGui.QPushButton('Stop', self)
self.buttonStop.setDisabled(True)
self.buttonStop.clicked.connect(self.handleButtonStop)
layout.addWidget(self.buttonStop)
self._process = QtCore.QProcess(self)
self._process.started.connect(self.handleStarted)
self._process.finished.connect(self.handleFinished)
self._process.error.connect(self.handleError)
self._time = QtCore.QTime()
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self.handleTimeout)
def closeEvent(self, event):
if self._timer.isActive():
event.ignore()
else:
QtGui.QWidget.closeEvent(self, event)
def handleButtonStart(self):
self._running = True
self._process.start('ffmpeg', [
'-f', 'concat', '-i', 'input.txt',
'-c', 'copy', '-y', 'output.mp4',
], QtCore.QIODevice.ReadOnly)
def handleTimeout(self):
self.label.setText(
'Elapsed: %.*f' % (2, self._time.elapsed() / 1000.0))
def handleButtonStop(self):
if self._timer.isActive():
self._process.close()
def handleStarted(self):
self.buttonStart.setDisabled(True)
self.buttonStop.setDisabled(False)
self._time.start()
self._timer.start(50)
def handleFinished(self):
self._timer.stop()
self.buttonStart.setDisabled(False)
self.buttonStop.setDisabled(True)
def handleError(self, error):
if error == QtCore.QProcess.CrashExit:
print('Process killed')
else:
print(self._process.errorString())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 200, 100)
window.show()
sys.exit(app.exec_())