Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Getting error messages from cmd window to plainTextEdit in QT

Getting error messages from cmd window to plainTextEdit in QT

Scheduled Pinned Locked Moved Solved Qt for Python
7 Posts 3 Posters 1.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sm2770s
    wrote on last edited by sm2770s
    #1

    I would like to display error messages in cmd window to the plainTextEdit in QT. I am not sure on how to pass this error messages to plainTextEdit. I was ablt to pipe standard output to text window in GUI but unable to pipe error to the text window.

    Below you can find some modified snippet of the code

    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtCore import QCoreApplication
    
    import sys
    import os
    
    # Piping the standard output (print/stdout command) to the GUI text window
    class StandardLog:
        def __init__(self, edit):
            self.out = sys.stdout
            self.textEdit = edit
    
        def write(self, message):
            # self.out.write(message)
            # self.textEdit.insertPlainText(message)
    
            self.textEdit.appendPlainText(message)
    
            self.textEdit.ensureCursorVisible()
    
            QCoreApplication.processEvents()
    
        def flush(self):
            self.out.flush()
    
    # Piping the standard error (stderr) to the GUI text window
    class ErrorLog:
        def __init__(self, edit):
            self.out = sys.stderr
            self.textEdit = edit
    
        def write(self, message):
            # self.out.write(message)
            # self.textEdit.insertPlainText(message)
            self.textEdit.appendPlainText(message)
            self.textEdit.ensureCursorVisible()
            QCoreApplication.processEvents()
    
        def flush(self):
            self.out.flush()
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(888, 797)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
            self.spinBox.setGeometry(QtCore.QRect(60, 210, 42, 22))
            self.spinBox.setMaximum(10000)
            self.spinBox.setObjectName("spinBox")
            self.spinBox_2 = QtWidgets.QSpinBox(self.centralwidget)
            self.spinBox_2.setGeometry(QtCore.QRect(240, 210, 61, 22))
            self.spinBox_2.setMaximum(10000)
            self.spinBox_2.setObjectName("spinBox_2")
            self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
            self.checkBox.setGeometry(QtCore.QRect(460, 220, 70, 17))
            self.checkBox.setObjectName("checkBox")
            self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget)
            self.checkBox_2.setGeometry(QtCore.QRect(670, 220, 70, 17))
            self.checkBox_2.setObjectName("checkBox_2")
            self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
            self.radioButton.setGeometry(QtCore.QRect(400, 300, 82, 17))
            self.radioButton.setObjectName("radioButton")
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setGeometry(QtCore.QRect(60, 170, 151, 16))
            self.label.setObjectName("label")
            self.label_2 = QtWidgets.QLabel(self.centralwidget)
            self.label_2.setGeometry(QtCore.QRect(230, 150, 121, 71))
            self.label_2.setObjectName("label_2")
            self.label_3 = QtWidgets.QLabel(self.centralwidget)
            self.label_3.setGeometry(QtCore.QRect(460, 180, 91, 16))
            self.label_3.setObjectName("label_3")
            self.label_4 = QtWidgets.QLabel(self.centralwidget)
            self.label_4.setGeometry(QtCore.QRect(650, 180, 121, 16))
            self.label_4.setObjectName("label_4")
            self.textEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
            self.textEdit.setGeometry(QtCore.QRect(30, 380, 811, 351))
            self.textEdit.setObjectName("textEdit")
            self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
            self.lineEdit_2.setGeometry(QtCore.QRect(50, 80, 231, 51))
            self.lineEdit_2.setObjectName("lineEdit_2")
            self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
            self.lineEdit_3.setGeometry(QtCore.QRect(382, 79, 201, 51))
            self.lineEdit_3.setObjectName("lineEdit_3")
            self.spinBox_3 = QtWidgets.QSpinBox(self.centralwidget)
            self.spinBox_3.setGeometry(QtCore.QRect(700, 80, 42, 22))
            self.spinBox_3.setObjectName("spinBox_3")
            self.label_5 = QtWidgets.QLabel(self.centralwidget)
            self.label_5.setGeometry(QtCore.QRect(70, 40, 47, 13))
            self.label_5.setObjectName("label_5")
            self.label_6 = QtWidgets.QLabel(self.centralwidget)
            self.label_6.setGeometry(QtCore.QRect(380, 30, 121, 16))
            self.label_6.setObjectName("label_6")
            self.label_7 = QtWidgets.QLabel(self.centralwidget)
            self.label_7.setGeometry(QtCore.QRect(690, 30, 47, 13))
            self.label_7.setObjectName("label_7")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 888, 21))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
            self.output = StandardLog(self.textEdit)
            self.error = ErrorLog(self.plainTextEdit)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
            self.checkBox.setText(_translate("MainWindow", "CheckBox"))
            self.checkBox_2.setText(_translate("MainWindow", "CheckBox"))
            self.radioButton.setText(_translate("MainWindow", "process"))
            self.label.setText(_translate("MainWindow", "Iterations for xxxxx"))
            self.label_2.setText(_translate("MainWindow", "Iteration for yyyyy"))
            self.label_3.setText(_translate("MainWindow", "Enable Output"))
            self.label_4.setText(_translate("MainWindow", "Enable zzzzz ))
            self.label_5.setText(_translate("MainWindow", "ip"))
            self.label_6.setText(_translate("MainWindow", "ip2"))
            self.label_7.setText(_translate("MainWindow", "idx"))
    
        def spin(self):
            #print("Selected Number of Iterations")
            self.output.write(str(self.spinBox.value()))
            print(self.spinBox.value())
    
            
        def spin2(self):
            self.output.write(str(self.spinBox_2.value()))
            print(self.spinBox_2.value())
            
        def printVal(self):
            self.output.write(str(self.checkBox.checkStateSet()))
            print(self.checkBox.checkStateSet())
            
        def printVal2(self):
            self.output.write(str(self.checkBox_2.checkStateSet()))
            print(self.checkBox_2.checkStateSet())
            
        def printip(self):
            self.output.write(str(self.lineEdit_2.text()))
            #print(self.lineEdit_2.text())
    
        def printip_1(self):
            self.output.write(str(self.lineEdit_3.text()))
            #print(self.lineEdit_2.text())
            
        def run_calib(self):
            #print("Process Started")
            os.system("process.exe 172.188.1.10 172.168.1.8 1")
            
            
    window = Ui_MainWindow()
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    window.setupUi(MainWindow)
    MainWindow.show()
    
    window.spinBox.valueChanged.connect(window.spin)
    window.spinBox_2.valueChanged.connect(window.spin2)
    window.checkBox.stateChanged.connect(window.printVal)
    window.checkBox_2.stateChanged.connect(window.printVal2)
    window.lineEdit_2.editingFinished.connect(window.printip)
    window.lineEdit_3.editingFinished.connect(window.printip_1)
    
       
    sys.exit(app.exec_())
    

    Please ignore namings as i purposefully changed all the names. The main idea is here i have one executable which i made by using c++ however i wanted to add few user friendly modifications for example no of iterations and so on.. so i thought i will create one simple gui and was able to do most part of it but stuck at this piping Stderr messages to qt.

    However, I am bit confused to get this error messages into the plainTextEdit box in GUI. For example if there is no file named process.exe it throws process.exe is not there in cmd but i would like to throw the same message in my GUI.

    Thanks in Advance :-)

    P.S I already tried using ErrorLog class above inside the run_calib function but it doesnt do what i was expecting. This part is not reflected in the code

    JonBJ 1 Reply Last reply
    0
    • S sm2770s

      I would like to display error messages in cmd window to the plainTextEdit in QT. I am not sure on how to pass this error messages to plainTextEdit. I was ablt to pipe standard output to text window in GUI but unable to pipe error to the text window.

      Below you can find some modified snippet of the code

      from PyQt5 import QtCore, QtGui, QtWidgets
      from PyQt5.QtCore import QCoreApplication
      
      import sys
      import os
      
      # Piping the standard output (print/stdout command) to the GUI text window
      class StandardLog:
          def __init__(self, edit):
              self.out = sys.stdout
              self.textEdit = edit
      
          def write(self, message):
              # self.out.write(message)
              # self.textEdit.insertPlainText(message)
      
              self.textEdit.appendPlainText(message)
      
              self.textEdit.ensureCursorVisible()
      
              QCoreApplication.processEvents()
      
          def flush(self):
              self.out.flush()
      
      # Piping the standard error (stderr) to the GUI text window
      class ErrorLog:
          def __init__(self, edit):
              self.out = sys.stderr
              self.textEdit = edit
      
          def write(self, message):
              # self.out.write(message)
              # self.textEdit.insertPlainText(message)
              self.textEdit.appendPlainText(message)
              self.textEdit.ensureCursorVisible()
              QCoreApplication.processEvents()
      
          def flush(self):
              self.out.flush()
      
      class Ui_MainWindow(object):
          def setupUi(self, MainWindow):
              MainWindow.setObjectName("MainWindow")
              MainWindow.resize(888, 797)
              self.centralwidget = QtWidgets.QWidget(MainWindow)
              self.centralwidget.setObjectName("centralwidget")
              self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
              self.spinBox.setGeometry(QtCore.QRect(60, 210, 42, 22))
              self.spinBox.setMaximum(10000)
              self.spinBox.setObjectName("spinBox")
              self.spinBox_2 = QtWidgets.QSpinBox(self.centralwidget)
              self.spinBox_2.setGeometry(QtCore.QRect(240, 210, 61, 22))
              self.spinBox_2.setMaximum(10000)
              self.spinBox_2.setObjectName("spinBox_2")
              self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
              self.checkBox.setGeometry(QtCore.QRect(460, 220, 70, 17))
              self.checkBox.setObjectName("checkBox")
              self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget)
              self.checkBox_2.setGeometry(QtCore.QRect(670, 220, 70, 17))
              self.checkBox_2.setObjectName("checkBox_2")
              self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
              self.radioButton.setGeometry(QtCore.QRect(400, 300, 82, 17))
              self.radioButton.setObjectName("radioButton")
              self.label = QtWidgets.QLabel(self.centralwidget)
              self.label.setGeometry(QtCore.QRect(60, 170, 151, 16))
              self.label.setObjectName("label")
              self.label_2 = QtWidgets.QLabel(self.centralwidget)
              self.label_2.setGeometry(QtCore.QRect(230, 150, 121, 71))
              self.label_2.setObjectName("label_2")
              self.label_3 = QtWidgets.QLabel(self.centralwidget)
              self.label_3.setGeometry(QtCore.QRect(460, 180, 91, 16))
              self.label_3.setObjectName("label_3")
              self.label_4 = QtWidgets.QLabel(self.centralwidget)
              self.label_4.setGeometry(QtCore.QRect(650, 180, 121, 16))
              self.label_4.setObjectName("label_4")
              self.textEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
              self.textEdit.setGeometry(QtCore.QRect(30, 380, 811, 351))
              self.textEdit.setObjectName("textEdit")
              self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
              self.lineEdit_2.setGeometry(QtCore.QRect(50, 80, 231, 51))
              self.lineEdit_2.setObjectName("lineEdit_2")
              self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
              self.lineEdit_3.setGeometry(QtCore.QRect(382, 79, 201, 51))
              self.lineEdit_3.setObjectName("lineEdit_3")
              self.spinBox_3 = QtWidgets.QSpinBox(self.centralwidget)
              self.spinBox_3.setGeometry(QtCore.QRect(700, 80, 42, 22))
              self.spinBox_3.setObjectName("spinBox_3")
              self.label_5 = QtWidgets.QLabel(self.centralwidget)
              self.label_5.setGeometry(QtCore.QRect(70, 40, 47, 13))
              self.label_5.setObjectName("label_5")
              self.label_6 = QtWidgets.QLabel(self.centralwidget)
              self.label_6.setGeometry(QtCore.QRect(380, 30, 121, 16))
              self.label_6.setObjectName("label_6")
              self.label_7 = QtWidgets.QLabel(self.centralwidget)
              self.label_7.setGeometry(QtCore.QRect(690, 30, 47, 13))
              self.label_7.setObjectName("label_7")
              MainWindow.setCentralWidget(self.centralwidget)
              self.menubar = QtWidgets.QMenuBar(MainWindow)
              self.menubar.setGeometry(QtCore.QRect(0, 0, 888, 21))
              self.menubar.setObjectName("menubar")
              MainWindow.setMenuBar(self.menubar)
              self.statusbar = QtWidgets.QStatusBar(MainWindow)
              self.statusbar.setObjectName("statusbar")
              MainWindow.setStatusBar(self.statusbar)
              self.output = StandardLog(self.textEdit)
              self.error = ErrorLog(self.plainTextEdit)
      
              self.retranslateUi(MainWindow)
              QtCore.QMetaObject.connectSlotsByName(MainWindow)
      
          def retranslateUi(self, MainWindow):
              _translate = QtCore.QCoreApplication.translate
              MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
              self.checkBox.setText(_translate("MainWindow", "CheckBox"))
              self.checkBox_2.setText(_translate("MainWindow", "CheckBox"))
              self.radioButton.setText(_translate("MainWindow", "process"))
              self.label.setText(_translate("MainWindow", "Iterations for xxxxx"))
              self.label_2.setText(_translate("MainWindow", "Iteration for yyyyy"))
              self.label_3.setText(_translate("MainWindow", "Enable Output"))
              self.label_4.setText(_translate("MainWindow", "Enable zzzzz ))
              self.label_5.setText(_translate("MainWindow", "ip"))
              self.label_6.setText(_translate("MainWindow", "ip2"))
              self.label_7.setText(_translate("MainWindow", "idx"))
      
          def spin(self):
              #print("Selected Number of Iterations")
              self.output.write(str(self.spinBox.value()))
              print(self.spinBox.value())
      
              
          def spin2(self):
              self.output.write(str(self.spinBox_2.value()))
              print(self.spinBox_2.value())
              
          def printVal(self):
              self.output.write(str(self.checkBox.checkStateSet()))
              print(self.checkBox.checkStateSet())
              
          def printVal2(self):
              self.output.write(str(self.checkBox_2.checkStateSet()))
              print(self.checkBox_2.checkStateSet())
              
          def printip(self):
              self.output.write(str(self.lineEdit_2.text()))
              #print(self.lineEdit_2.text())
      
          def printip_1(self):
              self.output.write(str(self.lineEdit_3.text()))
              #print(self.lineEdit_2.text())
              
          def run_calib(self):
              #print("Process Started")
              os.system("process.exe 172.188.1.10 172.168.1.8 1")
              
              
      window = Ui_MainWindow()
      app = QtWidgets.QApplication(sys.argv)
      MainWindow = QtWidgets.QMainWindow()
      window.setupUi(MainWindow)
      MainWindow.show()
      
      window.spinBox.valueChanged.connect(window.spin)
      window.spinBox_2.valueChanged.connect(window.spin2)
      window.checkBox.stateChanged.connect(window.printVal)
      window.checkBox_2.stateChanged.connect(window.printVal2)
      window.lineEdit_2.editingFinished.connect(window.printip)
      window.lineEdit_3.editingFinished.connect(window.printip_1)
      
         
      sys.exit(app.exec_())
      

      Please ignore namings as i purposefully changed all the names. The main idea is here i have one executable which i made by using c++ however i wanted to add few user friendly modifications for example no of iterations and so on.. so i thought i will create one simple gui and was able to do most part of it but stuck at this piping Stderr messages to qt.

      However, I am bit confused to get this error messages into the plainTextEdit box in GUI. For example if there is no file named process.exe it throws process.exe is not there in cmd but i would like to throw the same message in my GUI.

      Thanks in Advance :-)

      P.S I already tried using ErrorLog class above inside the run_calib function but it doesnt do what i was expecting. This part is not reflected in the code

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @sm2770s
      You are getting confused/trying to do things which won't work. Like

      self.out = sys.stderr
      self.textEdit = edit
      

      If you want to stick with Python os.system() to run external commands then it's a Python question and you'd have to look up how to capture its output. [I think you would need to look at subprocess module.]

      My recommendation/suggestion would be to do OS commands from a Qt UI app via Qt's QProcess module. Then you can use its way of accessing stdout/stderr, as well as signals/slots/asynchronicity, and still be able to ask about it in this forum. You will have to read through that topic and look at examples, because it's a bit much to explain.

      S 1 Reply Last reply
      1
      • JonBJ JonB

        @sm2770s
        You are getting confused/trying to do things which won't work. Like

        self.out = sys.stderr
        self.textEdit = edit
        

        If you want to stick with Python os.system() to run external commands then it's a Python question and you'd have to look up how to capture its output. [I think you would need to look at subprocess module.]

        My recommendation/suggestion would be to do OS commands from a Qt UI app via Qt's QProcess module. Then you can use its way of accessing stdout/stderr, as well as signals/slots/asynchronicity, and still be able to ask about it in this forum. You will have to read through that topic and look at examples, because it's a bit much to explain.

        S Offline
        S Offline
        sm2770s
        wrote on last edited by
        #3

        @JonB May be you are right! I will go through QProcess Module and try to access stdout and stderr and maybe others too.

        JonBJ 1 Reply Last reply
        0
        • S sm2770s

          @JonB May be you are right! I will go through QProcess Module and try to access stdout and stderr and maybe others too.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @sm2770s
          I can't give you all my code from an old Python (PyQt5) program I wrote because it's too large. It runs an arbitrary sub-process from a dialog, capturing all its output and displaying to user as it goes along. But here's an extract which is the guts of it, that may help you get going. If you can understand this and fill in the missing bits you will be good.

              def runProcessShowOutput(self, program: str, args: str, extraEnv: [(str, str)]=None):
                  # initialise the exit code
                  self.exitCode = -1
                  # create the process object
                  # start the process
                  # display the modal dialog
                  # program: string for the executable to run (*not* quoted)
                  # args: string of all command-line arguments (should be already quoted as required)
                  # extraEnv: optional array of [name, value] for any extra environment variables to be passed to process
                  self.process = QProcess()
                  # Set process that anything which goes to stderr is merged into stdout
                  self.process.setProcessChannelMode(QProcess.MergedChannels)
                  # Connect process signals
                  try:
                      # Qt 5.6+
                      self.process.errorOccurred.connect(lambda error: self.processErrorOccurred(error))
                  except AttributeError:
                      pass
                  self.process.started.connect(self.processStarted)
                  self.process.finished.connect(lambda exitCode, exitStatus: self.processFinished(exitCode, exitStatus))
                  self.process.readyReadStandardOutput.connect(self.processReadyReadStandardOutput)
                  # Add any additional environment variables to process
                  if extraEnv and len(extraEnv):
                      env = self.process.processEnvironment()
                      for (name, value) in extraEnv:
                          env.insert(name, value)
                      self.process.setProcessEnvironment(env)
                  # Start the process
                  self.process.start("\"{}\" {}".format(program, args))
                  # **NOTE**
                  # Don't do it via a single string of arguments, already quoted, as it was at the time I wrote this on the line above
                  # Pass into this method a *list* of (unquoted) arguments now
                  # and use the `self.process.start(command, arguments)` overload
          
                  # Show the dialog modal
                  self.exec()
          

          Don't worry about the "environment" stuff or the modal dialog.

          And here are a couple of the support methods:

              def processReadyReadStandardOutput(self):
                  # read all output available at this point
                  byteArray = self.process.readAllStandardOutput()
                  # convert QByteArray to str
                  # Linux: the decoder should always be "utf-8"
                  # Windows: after *enormous* investigations "utf-8" *mostly* works
                  #          but if the output contains a "funny" character like "£"
                  #          it will cause a conversion error
                  #          then the correct decoder to use is what the command "chcp" says
                  #          (e.g. "cp850" for Code Page 850 in UK) to avoid the error *and* correctly display the £
                  text = ""
                  try:
                      try:
                          text = byteArray.data().decode('utf-8')
                      except UnicodeDecodeError:
                          from common import osfunctions
                          if osfunctions.isWindows():
                              text = byteArray.data().decode('cp850')
                  except:
                      # if all this fails for whatever reason (just in case)
                      # just output a load of "?"s the length of the output
                      # anything is better than throwing an exception here
                      text = "?" * len(byteArray)
                  self.appendInformativeText(text)
          
              def processFinished(self, exitCode: int, exitStatus: QProcess.ExitStatus):
                  self.process = None
                  output = "\nCommand exit code: {}\n".format(exitCode)
                  self.appendInformativeText(output)
                  self.exitCode = exitCode
                  if exitCode == 0:
                      text = "Command ran successfully"
                  else:
                      text = "Command ran, but with non-zero exit code"
                  self.setText(text)
                  self.disableTerminate()
          
          S 1 Reply Last reply
          1
          • JonBJ JonB

            @sm2770s
            I can't give you all my code from an old Python (PyQt5) program I wrote because it's too large. It runs an arbitrary sub-process from a dialog, capturing all its output and displaying to user as it goes along. But here's an extract which is the guts of it, that may help you get going. If you can understand this and fill in the missing bits you will be good.

                def runProcessShowOutput(self, program: str, args: str, extraEnv: [(str, str)]=None):
                    # initialise the exit code
                    self.exitCode = -1
                    # create the process object
                    # start the process
                    # display the modal dialog
                    # program: string for the executable to run (*not* quoted)
                    # args: string of all command-line arguments (should be already quoted as required)
                    # extraEnv: optional array of [name, value] for any extra environment variables to be passed to process
                    self.process = QProcess()
                    # Set process that anything which goes to stderr is merged into stdout
                    self.process.setProcessChannelMode(QProcess.MergedChannels)
                    # Connect process signals
                    try:
                        # Qt 5.6+
                        self.process.errorOccurred.connect(lambda error: self.processErrorOccurred(error))
                    except AttributeError:
                        pass
                    self.process.started.connect(self.processStarted)
                    self.process.finished.connect(lambda exitCode, exitStatus: self.processFinished(exitCode, exitStatus))
                    self.process.readyReadStandardOutput.connect(self.processReadyReadStandardOutput)
                    # Add any additional environment variables to process
                    if extraEnv and len(extraEnv):
                        env = self.process.processEnvironment()
                        for (name, value) in extraEnv:
                            env.insert(name, value)
                        self.process.setProcessEnvironment(env)
                    # Start the process
                    self.process.start("\"{}\" {}".format(program, args))
                    # **NOTE**
                    # Don't do it via a single string of arguments, already quoted, as it was at the time I wrote this on the line above
                    # Pass into this method a *list* of (unquoted) arguments now
                    # and use the `self.process.start(command, arguments)` overload
            
                    # Show the dialog modal
                    self.exec()
            

            Don't worry about the "environment" stuff or the modal dialog.

            And here are a couple of the support methods:

                def processReadyReadStandardOutput(self):
                    # read all output available at this point
                    byteArray = self.process.readAllStandardOutput()
                    # convert QByteArray to str
                    # Linux: the decoder should always be "utf-8"
                    # Windows: after *enormous* investigations "utf-8" *mostly* works
                    #          but if the output contains a "funny" character like "£"
                    #          it will cause a conversion error
                    #          then the correct decoder to use is what the command "chcp" says
                    #          (e.g. "cp850" for Code Page 850 in UK) to avoid the error *and* correctly display the £
                    text = ""
                    try:
                        try:
                            text = byteArray.data().decode('utf-8')
                        except UnicodeDecodeError:
                            from common import osfunctions
                            if osfunctions.isWindows():
                                text = byteArray.data().decode('cp850')
                    except:
                        # if all this fails for whatever reason (just in case)
                        # just output a load of "?"s the length of the output
                        # anything is better than throwing an exception here
                        text = "?" * len(byteArray)
                    self.appendInformativeText(text)
            
                def processFinished(self, exitCode: int, exitStatus: QProcess.ExitStatus):
                    self.process = None
                    output = "\nCommand exit code: {}\n".format(exitCode)
                    self.appendInformativeText(output)
                    self.exitCode = exitCode
                    if exitCode == 0:
                        text = "Command ran successfully"
                    else:
                        text = "Command ran, but with non-zero exit code"
                    self.setText(text)
                    self.disableTerminate()
            
            S Offline
            S Offline
            sm2770s
            wrote on last edited by sm2770s
            #5

            @JonB Thanks Jon. SubProcess Module helped me to fix that. Thanks for the Quick help. For anyone who need in future.

            By way of a fairly minimal demo, here's a quick terminal emulator that takes a command, executes it and writes the stdout and stderr to a QTextEdit in green and red respectively:
            Special Mention to vrrorx from reddit. This part is copied from her code from reddit.

            import sys
            import subprocess as sp
            import PyQt5.QtWidgets as qtw
            import PyQt5.QtCore as qtc
            import PyQt5.QtGui as qtg
            
            
            class Demo(qtw.QWidget):
                def __init__(self):
                    super().__init__()
                    self.ui()
                    self.show()
            
                def ui(self):
                    layout = qtw.QVBoxLayout()
                    self.setLayout(layout)
            
                    self.text = qtw.QTextEdit()
                    self.text.setReadOnly(True)
                    layout.addWidget(self.text)
            
                    self.command = qtw.QLineEdit()
                    self.command.setPlaceholderText("Enter command...")
                    layout.addWidget(self.command)
            
                    self.button = qtw.QPushButton("Execute")
                    self.button.clicked.connect(self.execute)
                    layout.addWidget(self.button)
            
                def execute(self):
                    command = self.command.text()
                    self.command.clear()
                    self.text.setTextColor(qtg.QColor(0, 0, 0))  # Black
                    self.text.append(f"$ {command}")
            
                    p = sp.run(command, capture_output=True, text=True, shell=True)
            
                    if p.stdout:
                        self.text.setTextColor(qtg.QColor(0, 128, 0))  # Green
                        self.text.append(p.stdout)
            
                    if p.stderr:
                        self.text.setTextColor(qtg.QColor(255, 0, 0))  # Red
                        self.text.append(p.stderr)
            
            
            if __name__ == "__main__":
                app = qtw.QApplication(sys.argv)
                demo = Demo()
                sys.exit(app.exec_())
            
            SGaistS 1 Reply Last reply
            0
            • S sm2770s

              @JonB Thanks Jon. SubProcess Module helped me to fix that. Thanks for the Quick help. For anyone who need in future.

              By way of a fairly minimal demo, here's a quick terminal emulator that takes a command, executes it and writes the stdout and stderr to a QTextEdit in green and red respectively:
              Special Mention to vrrorx from reddit. This part is copied from her code from reddit.

              import sys
              import subprocess as sp
              import PyQt5.QtWidgets as qtw
              import PyQt5.QtCore as qtc
              import PyQt5.QtGui as qtg
              
              
              class Demo(qtw.QWidget):
                  def __init__(self):
                      super().__init__()
                      self.ui()
                      self.show()
              
                  def ui(self):
                      layout = qtw.QVBoxLayout()
                      self.setLayout(layout)
              
                      self.text = qtw.QTextEdit()
                      self.text.setReadOnly(True)
                      layout.addWidget(self.text)
              
                      self.command = qtw.QLineEdit()
                      self.command.setPlaceholderText("Enter command...")
                      layout.addWidget(self.command)
              
                      self.button = qtw.QPushButton("Execute")
                      self.button.clicked.connect(self.execute)
                      layout.addWidget(self.button)
              
                  def execute(self):
                      command = self.command.text()
                      self.command.clear()
                      self.text.setTextColor(qtg.QColor(0, 0, 0))  # Black
                      self.text.append(f"$ {command}")
              
                      p = sp.run(command, capture_output=True, text=True, shell=True)
              
                      if p.stdout:
                          self.text.setTextColor(qtg.QColor(0, 128, 0))  # Green
                          self.text.append(p.stdout)
              
                      if p.stderr:
                          self.text.setTextColor(qtg.QColor(255, 0, 0))  # Red
                          self.text.append(p.stderr)
              
              
              if __name__ == "__main__":
                  app = qtw.QApplication(sys.argv)
                  demo = Demo()
                  sys.exit(app.exec_())
              
              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              @sm2770s said in Getting error messages from cmd window to plainTextEdit in QT:

              Special Mention to vrrorx from reddit. This part is copied from her code from reddit.

              In that case it would be nice to provide a link to the relevant material.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              S 1 Reply Last reply
              1
              • SGaistS SGaist

                Hi,

                @sm2770s said in Getting error messages from cmd window to plainTextEdit in QT:

                Special Mention to vrrorx from reddit. This part is copied from her code from reddit.

                In that case it would be nice to provide a link to the relevant material.

                S Offline
                S Offline
                sm2770s
                wrote on last edited by
                #7

                @SGaist Sorry for the little late reply.

                https://www.reddit.com/r/learnpython/comments/la5yze/how_to_display_error_messages_in_cmd_window_to/

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved