Я хочу, чтобы список команд обрабатывался с помощью QProcess и чтобы его вывод был добавлен в имеющееся у меня текстовое поле. Я нашел эти две страницы, которые, кажется, выполняют все, что мне нужно (обновление пользовательского интерфейса, а не замораживание пользовательского интерфейса с помощью QThread):
Печать стандартного вывода QProcess, только если он содержит подстроку
https://nikolak.com/pyqt-threading-tutorial/
Итак, я попытался объединить эти два ....
import sys
from PySide import QtGui, QtCore
class commandThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
self.cmdList = None
self.process = QtCore.QProcess()
def __del__(self):
self.wait()
def command(self):
# print 'something'
self.process.start('ping', ['127.0.0.1'])
processStdout = str(self.process.readAll())
return processStdout
def run(self):
for i in range(3):
messages = self.command()
self.emit(QtCore.SIGNAL('dataReady(QString)'), messages)
# self.sleep(1)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def dataReady(self,outputMessage):
cursorOutput = self.output.textCursor()
cursorSummary = self.summary.textCursor()
cursorOutput.movePosition(cursorOutput.End)
cursorSummary.movePosition(cursorSummary.End)
# Update self.output
cursorOutput.insertText(outputMessage)
# Update self.summary
for line in outputMessage.split("\n"):
if 'TTL' in line:
cursorSummary.insertText(line)
self.output.ensureCursorVisible()
self.summary.ensureCursorVisible()
def initUI(self):
layout = QtGui.QHBoxLayout()
self.runBtn = QtGui.QPushButton('Run')
self.runBtn.clicked.connect(self.callThread)
self.output = QtGui.QTextEdit()
self.summary = QtGui.QTextEdit()
layout.addWidget(self.runBtn)
layout.addWidget(self.output)
layout.addWidget(self.summary)
centralWidget = QtGui.QWidget()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
# self.process.started.connect(lambda: self.runBtn.setEnabled(False))
# self.process.finished.connect(lambda: self.runBtn.setEnabled(True))
def callThread(self):
self.runBtn.setEnabled(False)
self.get_thread = commandThread()
# print 'this this running?'
self.connect(self.get_thread, QtCore.SIGNAL("dataReady(QString)"), self.dataReady)
self.connect(self.get_thread, QtCore.SIGNAL("finished()"), self.done)
def done(self):
self.runBtn.setEnabled(True)
def main():
app = QtGui.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Проблема в том, что, как только я нажимаю кнопку «Выполнить»текстовое поле справа, кажется, не заполняется, и я больше не получаю никаких ошибок, поэтому я не уверен, что происходит.
Я также пытался сослаться на эту страницу, но мне кажется, что я уже эмулируючто он описывает ...?
https://www.qtcentre.org/threads/46056-QProcess-in-a-loop-works-but
В конечном счете, я хочу построить главное окно, чтобы отправить серию команд через подпроцесс / QProcess, и немного открытьокно журнала, которое постоянно обновляет информацию о ходе выполнения, отображая вывод консоли. Подобно тому, что вы видите в пакетах установщика ...
Я чувствую, что я так близок к ответу, но так далеко. Кто-нибудь может вмешаться в это?
РЕДАКТИРОВАТЬ: так, чтобы ответить на вопрос eyllanesc, список команд должен быть запущен один после завершения предыдущей, так как команда, которую я планирую использовать, будет очень ЦПинтенсивно, и я не могу иметь более одного процесса. также время завершения каждой команды будет полностью меняться, поэтому я не могу просто произвольно удерживать, как с time.sleep (), поскольку некоторые могут завершаться быстрее / медленнее, чем другие. поэтому в идеале выяснение того, когда процесс завершился, должно запустить другую команду (вот почему у меня есть цикл for в этом примере, чтобы представить это).
Я также решил использовать потоки, потому что, очевидно, это был один из способов предотвращенияпользовательский интерфейс для остановки во время работы процесса, поэтому я предположил, что мне нужно использовать это, чтобы иметь вид живого фида / обновления в текстовом поле.
другая вещь в пользовательском интерфейсе, в идеале я бы добавилчтобы обновить текстовое поле с помощью журналов консоли, я бы хотел, чтобы у него была какая-то метка, которая будет обновляться, которая будет что-то вроде «2 из 10 выполненных заданий». что-то вроде этого:
Было бы неплохо, когда перед обработкой новой команды в текстовое поле можно было добавить собственное сообщение с указаниемкакая команда выполняется ...