Terminal comme une application à PySide

je fais une application dans PySide et je veux ajouter une Console/Terminal comme l'écran, où vous avez un prompt et vous pouvez taper des commandes. Comment serais-je capable de l'accomplir. Je devine une combinaison de QPlainTextEdit / QTextEdit pour la sortie et QLineEdit pour L'invite réelle. Est-il une meilleure façon de le faire?

3
demandé sur user1976336 2013-03-15 19:37:11

2 réponses

vous pouvez vérifier Spyder. Ils utilisent PyQt (qui est similaire) et ont un terminal. Je pense que vous pouvez importer leur terminal widget, mais je n'ai pas joué avec.

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

aussi, c'est de loin mon éditeur de python préféré!

j'ai passé beaucoup de temps à essayer de trouver quelque chose comme cela, mais en vain. Bonne chance!

0
répondu Garrett Berg 2013-03-15 17:21:10

j'ai fait cela avec un qplaintextedit personnalisé et un QLineEdit personnalisé. J'avais aussi une étiquette d'indicateur qui afficherait "> > > " sur le terminal pour afficher les entrées de l'utilisateur. Il a besoin de plus de travail. Le meilleur moyen serait de créer votre propre widget personnalisé basé sur un QTextEdit et votre propre io gestionnaire. Ci-dessous est un exemple de ma méthode d'exécution avec self.l'entrée étant QLineEdit et self.vue étant le QTextEdit. Il devrait vous obtenir l'idée générale.

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
0
répondu justengel 2013-11-20 14:57:06