Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Get output of command run by QProcess



  • Hi,
    I'm on Linux and using python. I'm having trouble get readAllStandardOutput() to work. It keeps returning nothing no matter what I do. Here's my code:

    import sys
    from pyqtgraph import QtGui, QtCore

    class embeddedTerminal(QtGui.QWidget, QtCore.QProcess):

    def init(self):

      QtGui.QWidget.__init__(self)
      self._processes = []
      self.resize(800, 600)
      self.terminal = QtGui.QLabel(self)
      self.vLayout = QtGui.QVBoxLayout(self)
      self.vLayout.addWidget(self.terminal)
               self.hLayout = QtGui.QHBoxLayout()
      """self._start_process(
          'xterm',
          ['-into', str(self.terminal.winId()),
           '-e', 'tmux', 'new', '-s', 'my_session']
      )"""
      self.vLayout.addLayout(self.hLayout)
      self.arrowLabel = QtGui.QLabel(">")
      self.lineEdit = QtGui.QLineEdit()
      self.hLayout.addWidget(self.arrowLabel)
      self.hLayout.addWidget(self.lineEdit)
      self.lineEdit.returnPressed.connect(self.runCommand)
      #self.lineEdit.setPlaceholderText(">")
      self.process = QtCore.QProcess()
    

    def runCommand(self):

      self.command = self.lineEdit.text()
      self.command = unicode.encode(self.command)
      self.command = self.command.split(" ")
      self.normalizedCommand = []
      self.separator = " "
      print(self.separator.join(self.command))
      self.process.start("/usr/bin/gnome-terminal", ["--command", self.separator.join(self.command)])
      #self.process.write("--command " + self.separator.join(self.command))
      self.lineEdit.clear()	
      self.process.waitForFinished()
      #self.process.closeWriteChannel()
      self.process.readyReadStandardOutput.connect(self.updateOutput)
      #while self.process.waitForFinished():
      	#QtCore.qDebug(self.process.readAll())
    

    def updateOutput(self):

      #self.process.readAllStandardOutput()
      QtCore.qDebug(self.process.readAllStandardOutput())
      #print(self.process.readAllStandardOutput())
      #print("this ran")
      self.terminal.setText(str(self.process.readAllStandardOutput()))
    

    if name == "main":
    app = QtGui.QApplication(sys.argv)
    main = embeddedTerminal()
    main.show()
    sys.exit(app.exec_())

    I've looked through quite a few similar questions, but the solutions never seem to work. Thanks for any help.


  • Lifetime Qt Champion

    Hi and welcome to the forums.

    Just as a thought.

    Did you try with some simple command like ls instead of
    gnome-terminal.
    I mean gnome-terminal is full blown "exe" and i wonder if QProcess can actually see what runs
    inside it.



  • @mrjj Hi,

    I couldn't figure out how to just straight up run a command using start() without defining what program to use, so I figured I would use the gnome-terminal, and I'm not able to readAllStandardOutput() from startDetached(). That said, when I did replace

    self.process.start("/usr/bin/gnome-terminal", ["--command", self.separator.join(self.command)])

    with

    self.process.start("/usr/bin/gnome-terminal", ["--command", "ls"])

    it did run. However, it just opened up an instance of terminal running ls. readAllStandardOutput() still returned nothing from what I can tell, if that makes sense.

    If I can't use terminal, what do you suggest I use instead in order to still have the ability to run commands?

    Edit: Now that I try it again, it doesn't even open up the terminal. I don't know what's going on.



  • @Hexrin
    What command(s) do you actually want to run? I'm not sure you're going to get the output from a terminal. And not sure why you would want to anyway.



  • @JonB
    This is part of a larger project where I was told "an embedded terminal would be nice to have". I'm not entirely sure what commands would be running here. Likely things to do with ROS, like roslaunch etc. As to why I would want to, it's so I can show the output in my embedded terminal? Like, updating the QLabel with the output rather than output randomly showing up in another terminal. Do you have any suggestions of what I could do instead?



  • @Hexrin
    A terminal (like xterm or gnome-terminal) shows its own output. You seem to want that, yet also something about displaying its output in your own QLabels? Seems to me it's an either/or? Either you wan to embed a terminal in a window, or you want to run commands and display their output yourself?

    If, to test, you change your command to, say, /bin/ls -l, you can have a go at running it, getting its output, and displaying it yourself.

    I think though you'll need to change your code. You set the slot on readyReadStandardOutput after you have waited for the process to finish. Not sure that will work. And not sure about mixing signals/slots with a waitFor...(). For thsi purpose after your wait...() just use QProcess::readAllStandardOutput().

    If it turns out you do not want to capture output and really want to embed a terminal/console, that's another matter.



  • @JonB
    Literally everything I could find online pointed to doing it this way rather than actually embedding a real terminal, and no one really seemed to know how to actually embed a real terminal. If you could tell me how to do this that would be very helpful.

    I'll try your other suggestions in a second. When I copy and pasted the code I forgot to comment out waitForFinished(), that was just a previous attempt at getting things to work, haha.



  • @Hexrin
    If I wanted to embed a terminal I would Google for Qt embed terminal. There are hits. Some are old, presumably abandoned, projects!

    If I wanted to run commands and grab their output that's not difficult, just a QProcess coding exercise.

    I can't tell you what you want because I don't know, And I have no idea what a ROS is, unless a character in Friends...?


  • Lifetime Qt Champion

    Hi
    Well the -into can work but i had no luck with Qt apps.
    I think you might be after something like
    https://github.com/lxqt/qtermwidget

    Heh
    -a ROS is, unless a character in Friends...?
    Its ross ? right ?
    I think its a Robot Operating system.



  • @JonB
    For the purposes of this post just assume I want to run any command in this terminal that I can in the regular terminal. Worst comes to worst, I can just have a button that opens the regular terminal or something.

    Yes haha, ROS is Robot Operating System.

    @mrjj
    I believe I am after something like that. Thanks, I will look into that.



  • @mrjj
    Yes to your qtermwidget, I came across that one, don't know if it's the right one. @Hexrin can investigate.

    Yes it's "Ross" ;-)

    What I really meant was: I haven't a clue what his "roslaunch" will do/look like/behave, and so what he will/will not want. :)


Log in to reply