【问题标题】:Terminal like app in PySidePySide 中的终端应用程序
【发布时间】:2013-03-15 15:37:11
【问题描述】:

我正在 PySide 中创建一个应用程序,我想添加一个类似控制台/终端的屏幕,您可以在其中看到提示并且可以键入命令。我怎么能做到这一点。我猜测 QPlainTextEdit/QTextEdit 的输出和实际提示的 QLineEdit 的某种组合。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python qt pyside


    【解决方案1】:

    您可以查看 Spyder。他们使用 PyQt(类似)并有一个终端。我认为您可以导入他们的终端小部件,但我没有玩过。

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

    另外,它是我目前最喜欢的 Python 编辑器!

    我花了很多时间试图找到这样的东西,但无济于事。祝你好运!

    【讨论】:

      【解决方案2】:

      我使用自定义 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
      

      【讨论】:

        猜你喜欢
        • 2013-08-28
        • 1970-01-01
        • 1970-01-01
        • 2017-02-10
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-07
        相关资源
        最近更新 更多