PySide: How to append text from different classes in QTextBrowser?

438 views Asked by At

I have a little application to run some commands and redirect the output in a QTextBrowser. It works fine when I'm using the buttons and command line in the console widget. But a want to use buttons in the side widgest, too. When I'm calling the function from the side widget it runs the command but I don't get a output in the QTextBrowser.

See a little example of the code below. Thanks a lot.

#!/usr/bin/env python

import sys
from PySide import QtCore, QtGui

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)

        # Add the Graphics widget
        self.graphicsViewWidget = GraphicsViewWidget(self)
        self.graphicsScene = self.graphicsViewWidget.scene()
        self.setCentralWidget(self.graphicsViewWidget)

        # Create side widget
        self.sideDock = QtGui.QDockWidget()
        self.sideDock.setAllowedAreas(QtCore.Qt.RightDockWidgetArea | QtCore.Qt.LeftDockWidgetArea)
        self.sideDock.setWindowTitle("SideWidget")
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.sideDock)
        self.sideWidget = SideWidget(self)
        self.sideDock.setWidget(self.sideWidget)

        # Create console widget
        self.consoleDock = QtGui.QDockWidget()
        self.consoleDock.setAllowedAreas(QtCore.Qt.RightDockWidgetArea | QtCore.Qt.LeftDockWidgetArea)
        self.consoleDock.setWindowTitle("Console")
        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.consoleDock)
        self.consoleWidget = ConsoleWidget(self)
        self.consoleDock.setWidget(self.consoleWidget)

        # Create menu
        fileMenu = self.menuBar().addMenu("&File")
        fileMenu.addAction(QtGui.QAction("&Quit...", self, shortcut="Ctrl+Q", triggered=self.close))

class GraphicsViewWidget(QtGui.QGraphicsView):
    def __init__(self, parent=None):
        QtGui.QGraphicsView.__init__(self, parent)


class SideWidget(QtGui.QWidget, ):

    def __init__(self, parent=None):

        QtGui.QWidget.__init__(self, parent)
        self.mainLayout = QtGui.QVBoxLayout(self)

        # Buttons
        self.execute_button = QtGui.QPushButton(self)
        self.execute_button.setText('Execute')
        self.execute_button.setFixedHeight(25)

        # Add Buttons to widget
        self.mainLayout.addWidget(self.execute_button)

        # Button actions
        self.execute_button.pressed.connect(self.execute_button_pressed)

    def execute_button_pressed(self):
        print('execute_button_pressed')

        ##########################################
        # want to run commands from here
        ##########################################

        cnsl=ConsoleWidget()
        cnsl.run_command()



        cnsl=RunCommands(self)
        cnsl.run_command()


        #RunCommands(self)




class ConsoleWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.mainLayout = QtGui.QVBoxLayout(self)

        # label
        self.label = QtGui.QLabel('Command Line', self)

        # commandline
        self.commandline = QtGui.QLineEdit(self)
        self.commandline.setFixedHeight(25)
        self.commandline.setToolTip('Run commands here')

        # The upper layout holds label and commandline
        upperLayout = QtGui.QHBoxLayout()
        upperLayout.addWidget(self.label)
        upperLayout.addWidget(self.commandline)

        # buttons
        self.dummy_button = QtGui.QPushButton(self)
        self.dummy_button.setText('Run Dummy')
        self.dummy_button.setToolTip('For testing')
        self.dummy_button.setFixedHeight(25)

        # Textbrowser
        #self.textbrowser = QtGui.QTextBrowser(self)
        self.textbrowser = QtGui.QTextEdit(self) # for typing in

        # The lower layout holds the textbrowser
        lowerLayout = QtGui.QVBoxLayout()
        lowerLayout.addWidget(self.dummy_button)
        lowerLayout.addWidget(self.textbrowser)

        # Add layouts to mainlayout
        self.mainLayout.addLayout(upperLayout)
        self.mainLayout.addLayout(lowerLayout)
        self.setLayout(self.mainLayout)

        # Button actions
        self.dummy_button.clicked.connect(self.run_command)
        self.commandline.returnPressed.connect(self.run_commandline)


    def run_command(self):

        print('run_command')
        command='cmd.exe /c echo test'
        print('Self   ',self)
        print('Command',command)

        self.textbrowser.append('test')

        # err and out
        ##self.runner.readyReadStandardError.connect(self.ErrInfo)
        ##self.runner.readyReadStandardOutput.connect(self.OutInfo)

        # Run command
        ##self.runner.start(command)

    def run_commandline(self):

        command_text = str(self.commandline.text())

        self.runner = QtCore.QProcess()

        # Make sure newInfo gets all output
        self.runner.readyReadStandardError.connect(self.ErrInfo)
        self.runner.readyReadStandardOutput.connect(self.OutInfo)

        # Run the command
        command='cmd.exe /c ' + command_text
        #print(command)
        self.runner.start(command)

        # clearing commandline
        self.commandline.clear()

    def ErrInfo(self):
        errString = str(self.runner.readAllStandardError())
        print('errString', errString, end=" ")
        self.textbrowser.append(errString)

    def OutInfo(self):
        outString = str(self.runner.readAllStandardOutput())
        print('outString', outString, end=" ")

        #cnsl=ConsoleWidget()

        self.textbrowser.append(outString)

class RunCommands(QtGui.QTextBrowser):
    def __init__(self, parent):

        print('RunCommands')
        QtGui.QTextBrowser.__init__(self, parent)

        # Textbrowser
        #self.textbrowser = ConsoleWidget().textbrowser
        self.run_command()

        #self.textbrowser.append('test2')

    def run_command(self):

        print('run_command')
        command='cmd.exe /c echo test'
        command='cmd.exe /c notepad'
        print('Self   ',self)
        print('Command',command)

        ConsoleWidget().textbrowser.append('test2')

        self.runner = QtCore.QProcess(self)

        # err and out
        self.runner.readyReadStandardError.connect(self.ErrInfo)
        self.runner.readyReadStandardOutput.connect(self.OutInfo)

        # Run command
        self.runner.start(command)


    def run_commandline(self):

        command_text = str(self.commandline.text())

        self.runner = QtCore.QProcess()

        # err and out
        self.runner.readyReadStandardError.connect(self.ErrInfo)
        self.runner.readyReadStandardOutput.connect(self.OutInfo)

        # Run command
        command='cmd.exe /c ' + command_text
        #print(command)
        self.runner.start(command)

        # clearing commandline
        self.commandline.clear()

    def ErrInfo(self):
        errString = str(self.runner.readAllStandardError())
        print('errString', errString, end=" ")
        self.textbrowser.append(errString)

    def OutInfo(self):
        outString = str(self.runner.readAllStandardOutput())
        print('outString', outString, end=" ")
        self.textbrowser.append(outString)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
1

There are 1 answers

0
Mel On

It's a question of where do you create your widget and how to access them.

You have a MainWindow which has two child widgets: a sideWidget and a consoleWidget. Then, in the SideWidget.execute_button_pressed, you create another ConsoleWidget. This new widget is nowhere in your layout, so you just don't see it.

To connect the input of MainWindow.sideWidget (button clicked) to the output of MainWindow.consoleWidget (run a command and print text), you simply have to do it in the class MainWindow. Something like this:

class MainWindow(QtGui.QMainWindow):
    def __init__(self,parent=None):
        ...
        self.sideWidget.execute_button.clicked.connect(self.execute)
        ...

    def execute_function(self):
        print('execute_button_pressed')
        self.consoleWidget.run_command()

Or just in one line:

self.sideWidget.execute_button.clicked.connect(self.consoleWidget.run_command)