PyQt: множественный QProcess и вывод

1

У меня есть окно PyQt, которое вызывает несколько исполняемых файлов как QProcess. Как я могу перечислить результаты каждого процесса после последнего завершения? (что-то вроде process_result = ["result1", "result2",..]) Скажем, это выглядит так:

for i in list_of_processes:
    process = QtCore.QProcess()
    process.start(i)

Я могу читать с process.readyReadStandardOutput() как-то, но это довольно хаотично, потому что процессы выполняются параллельно. process.waitForFinished() не работает, потому что GUI замерзнет. Кроме того, я проверил следующую страницу о многопоточности: многопоточные приложения PyQt с QThreadPool. Другой вопрос похож, но мне тоже не помогло: Pyside: множественный вывод QProcess для TextEdit.

Теги:
pyqt4
pyqt
qprocess

1 ответ

1
Лучший ответ

Возможным решением является создание класса, который управляет процессами, и который испускает один сигнал, когда все процессы завершатся по мере необходимости.

import sys

from functools import partial

from PyQt4 import QtCore, QtGui


class TaskManager(QtCore.QObject):
    resultsChanged = QtCore.pyqtSignal(list)

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)
        self.results = []
        self.m_processes = []
        self.number_process_running = 0

    def start_process(self, programs):
        for i, program in enumerate(programs):
            process = QtCore.QProcess(self)
            process.readyReadStandardOutput.connect(partial(self.onReadyReadStandardOutput, i))
            process.start(program)
            self.m_processes.append(process)
            self.results.append("")
            self.number_process_running += 1

    def onReadyReadStandardOutput(self, i):
        process = self.sender()
        self.results[i] = process.readAllStandardOutput()
        self.number_process_running -= 1
        if self.number_process_running <= 0:
            self.resultsChanged.emit(self.results)

def on_finished(results):
    print(results)
    QtCore.QCoreApplication.quit()

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    manager = TaskManager()
    manager.start_process(["ls", "ls"])
    manager.resultsChanged.connect(on_finished)
    sys.exit(app.exec_())
  • 0
    Большое спасибо, это помогло! Кроме того, мне было интересно, есть ли способ поставить процессы в очередь, чтобы избежать перегрузки потоков. Допустим, мой список программ очень длинный, что я мог сделать?
  • 0
    Извините, я имел в виду «перегрузка процессов». Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню