2013-03-15 71 views
3

我正在PySide中創建一個應用程序,我想添加一個控制檯/終端屏幕,在這裏你有一個提示符,你可以輸入命令。我將如何能夠做到這一點。我猜測輸出的QPlainTextEdit/QTextEdit和實際提示的QLineEdit的組合。有一個更好的方法嗎?終端在PySide中的應用程序

回答

0

你可以看看Spyder。他們使用PyQt(這是相似的),並有一個終端。我想你可以導入他們的終端小部件,但我沒有玩過它。

https://code.google.com/p/spyderlib/

而且,這是我最喜歡的Python編輯迄今爲止!

我花了一段時間試圖找到像這樣的東西,但無濟於事。祝你好運!

0

我用一個自定義的QPlainTextEdit和自定義的QLineEdit來做到這一點。我還有一個指示標籤,可以在終端上顯示「>>>」以顯示用戶輸入。它需要更多的工作。最好的方法是創建基於QTextEdit和您自己的io處理程序的自定義小部件。下面是我的執行方法的一個例子,self.input是QLineEdit,self.view是QTextEdit。它應該爲你提供一般的想法。

import io, subprocess, shlex, code, rlcompleter, platform 

def execute(self, currentText=None): 
    """Execute runs the command given based on the console type. 

    If the console type is "both" then execute will run python commands 
    unless the user give the input ::os::command or ("::(platform.syste())::command"). 
    Otherwise the console type will determine the what the input will execute with. 

    Args: 
     currentText(str): Text to execute. None will run the text from the QLineEdit self.input. 
    """ 
    # Check for given text 
    if currentText is None: 
     currentText = self.input.text() 
     self.input.clear() 
     self.view.display(currentText, "input") 
    else: 
     cmd = re.search("^>>>", currentText) # search for start only 
     if cmd is None: 
      currentText = ">>>" + currentText 
     else: 
      self.view.display(currentText, "input") 
    # end 

    # Variables 
    self.completer.clear() 
    cmdString = re.sub("^>>>", "", currentText) 
    result = None 
    displayType = "output" 
    run, cmdString = self.getRunType(cmdString) 

    try: 
     # Check where the output is going 
     sys.stdout = self.out = io.StringIO() 
     sys.stderr = sys.stdout 

     if run == "python": # Run python command 
      result = self._runInterpreter(cmdString) 
      displayType = "python" 

     elif run == "os": # Run os command 
      result = self._runSubprocess(cmdString) 
      displayType = "os" 
    except Exception as err: 
     result = str(err) 
     displayType = "Error" 

     notFoundPython = "NameError:" in result and "is not defined" in result 
     notFoundWindows = "returned non-zero exit status" in result 
     if notFoundPython or notFoundWindows: 
      result = "Command not found" 
    finally: 
     sys.stdout = self.old_stdout 
     sys.stderr = self.old_stdout 

     self.display(result, displayType) 
# end execute 

def getRunType(self, cmdString): 
    run = self._consoleType 

    # Check the run type 
    if self._consoleType == "both": 
     if re.search("^::python::", cmdString) is not None: 
      cmdString = re.sub("^::[a-z]*::", "", cmdString) 
      run = "python" 

     elif re.search("^(::os::|::"+platform.system()+"::)", cmdString) is not None: 
      cmdString = re.sub("^::[a-z]*::", "", cmdString) 
      run = "os" 
     else: 
      run = "python" 
    # end 

    return run, cmdString 
# end getRunType 

def _runInterpreter(self, cmdString, outIO=None, run=None): 
    # Check for a proper console type 
    if(self._consoleType != "both" and self._consoleType != "python"): 
     return 

    # Get the IO 
    if outIO is None: 
     outIO = sys.stdout 

    # Run python command  

    self.interpreter.push(cmdString) 

    # Check outIO 
    result = "Unreadable buffer: Check python's sys.stdout" 
    if isinstance(outIO, io.StringIO): 
     result = outIO.getvalue() 
    else: 
     if outIO.readable(): 
      result = str(outIO.readlines()) 

    # Check for error 
    if re.search("^Traceback", result) or re.search("[a-zA-z]*Error:", result): 
     raise ValueError(result) 

    return result 
# end _runInterpreter 

def _runSubprocess(self, cmdString, run=None): 
    # Check for a proper console type 
    if(self._consoleType != "both" and self._consoleType != "os"): 
     return 

    # Run OS command 
    cmd = shlex.split(cmdString) 
    result = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode("utf-8") 

    # Check for error 
    if re.search("^Traceback", result) or re.search("[a-zA-z]*Error:", result): 
     raise ValueError(result) 

    return result 
# end _runSubprocess