Как использовать Pyqt для запуска одного процесса после завершения другого? - PullRequest
0 голосов
/ 29 августа 2018

Я хотел бы запустить несколько файлов cmd, используя Pyqt5. В настоящее время я могу запустить только один файл cmd ... вот фрагмент кода:

def run(self):
    self.process = QProcess(self)
    self.process.started.connect(lambda: self.statusUpdate('Started'))
    self.process.finished.connect(lambda: self.statusUpdate('Finished'))
    self.process.start('test.cmd')

def statusUpdate(self, event):
    print(event)
    self.status = event

Вот простой cmd-файл, с которым я хочу протестировать:

echo TEST
echo TEST
echo TEST
PAUSE

Я заметил, что, хотя cmd-файл заканчивается, он никогда не печатает 'Finished'

Как запустить другой cmd-файл после завершения первого?

1 Ответ

0 голосов
/ 30 августа 2018

Для решения проблемы реализован класс, который выполняет команды последовательно, то есть он завершает одну задачу и выполняет следующую, пока все команды не будут выполнены.

from PyQt5 import QtCore, QtWidgets
from functools import partial


class SequentialManager(QtCore.QObject):
    finished = QtCore.pyqtSignal()
    resultsChanged = QtCore.pyqtSignal(QtCore.QByteArray)

    def __init__(self, parent=None):
        super(SequentialManager, self).__init__(parent)
        self.process = QtCore.QProcess(self)
        self.process.finished.connect(self.handleFinished)
        self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)

    def start(self, commands):
        self._commands = iter(commands)
        self.fetchNext()

    def fetchNext(self):
        try:
            command = next(self._commands)
        except StopIteration:
            return False
        else:
            self.process.start(command)
        return True

    def onReadyReadStandardOutput(self):
        result = self.process.readAllStandardOutput()
        self.resultsChanged.emit(result)

    def handleFinished(self):
        if not self.fetchNext():
            self.finished.emit()


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        vlay = QtWidgets.QVBoxLayout(self)
        self.te = QtWidgets.QTextEdit()
        self.te.setReadOnly(True)
        btn = QtWidgets.QPushButton("Start processes")
        vlay.addWidget(self.te)
        vlay.addWidget(btn)

        manager = SequentialManager(self)
        manager.resultsChanged.connect(self.onResultsChanged)

        commands = ["test1.cmd", "test2.cmd"]
        btn.clicked.connect(partial(manager.start, commands))

    def onResultsChanged(self, result):
        self.te.append(str(result, "utf-8"))


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
...