Как перенаправить вывод нескольких скриптов в QTextBrowser, используя PyQt4

Я использовал QtDesigner сделать волшебника и преобразовать .ui использованиефайла pyuic4,

Этот мастер имеет несколько страниц. На одной из страниц есть флажки. Флажки используются для выбора определенных скриптов Python для запуска.

Мой вопрос заключается в том, как я должен вызывать выбранные сценарии один за другим, а затем перенаправлять вывод в режиме реального времени на QTextBrowser виджет на любой из последующих страниц мастера.

Наконец, во время работы сценариев есть возможность временно отключить кнопки "Далее" и "Назад".

1 ответ

Использование QThread чтобы избежать зависания пользовательского интерфейса; запускать скрипты в ветке, используя subprocess.Popen с stdout=PIPEпрочитайте их вывод построчно, emit линии, и получить их в любом slot ты хочешь.

from PyQt4.QtGui import QTextBrowser, QApplication
from PyQt4.QtCore import pyqtSignal, QThread
from subprocess import Popen, PIPE
from Queue import Queue
from threading import Event

class ScriptRunner(QThread):
    # fired whenever a line from subprocess.stdout arrived
    got_line = pyqtSignal(unicode)

    def __init__(self):
        QThread.__init__(self)
        self.queue = Queue()
        self.put = self.queue.put
        self.stop_event = Event()
        self.start()

    def run(self):
        """thread function"""
        while 1:
            script = self.queue.get()
            if script is None:  # no more scripts
                break
            # run the script
            proc = Popen(script,  bufsize=1, stdout=PIPE, shell=True, 
                         universal_newlines=True)
            # read its output line by line
            while not self.stop_event.is_set():
                line = proc.stdout.readline()
                if not line:
                    break
                self.got_line.emit(line)

    def join(self):
        self.stop_event.set()
        self.put(None)
        self.wait()

if __name__ == '__main__':
    app = QApplication([])
    text_browser = QTextBrowser()
    text_browser.show()

    runner = ScriptRunner()
    # connect to got_line signal
    runner.got_line.connect(text_browser.insertPlainText)

    # schedule a script
    runner.put('''python -c "for i in range(25): print 'dada'; import time; time.sleep(.25)"''')
    # now force python to flush its stdout; note -u switch
    runner.put('''python -uc "for i in range(25): print 'haha'; import time; time.sleep(.25)"''')

    app.exec_()
    runner.join()

Однако обратите внимание, что из-за буферизации выходные данные сценариев могут приходить большими кусками, что затрудняет достижение гладкости в реальном времени, как в терминале. С питоном вы можете обойти это, передав -u переключиться на переводчика (не на сценарий).

Другие вопросы по тегам