2016-04-29 85 views
0

我已经使用QtDesigner作向导,并使用pyuic4转换的.ui文件多个脚本的输出重定向在QTextBrowser中被。如何使用PyQt4的

此向导有多个页面。其中一个页面包含复选框。复选框用于选择要运行的某些Python脚本。

我的问题是我应该如何去调用所选择的脚本一前一后,其后,重定向实时输出到一个QTextBrowser部件在任何后续的向导页面(或多个)。

最后,在脚本运行时,有一个选项可以临时禁用下一个和后退按钮。

回答

0

使用QThread来避免UI冻结; 在线程中运行脚本使用subprocess.Popenstdout=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() 

不过请注意,由于缓冲脚本的输出可能会在大块, 使其难以实现实时平滑像终端。 使用python,你可以通过将-u切换到解释器(而不是脚本)来规避这种情况。