Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QProcess::execute capture output
Forum Update on Monday, May 27th 2025

QProcess::execute capture output

Scheduled Pinned Locked Moved Solved General and Desktop
qprocessexecute
13 Posts 3 Posters 28.7k 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
    SGaist
    Lifetime Qt Champion
    wrote on 22 Apr 2017, 21:15 last edited by
    #2

    Hi,

    Isn't rather readyReadStandardOutput what you are looking for ?

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

    1 Reply Last reply
    1
    • J Offline
      J Offline
      Jan-Willem
      wrote on 24 Apr 2017, 08:56 last edited by
      #3

      @SGaist

      I made a simple example.

      // in constructor
      connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
      
      // slot connected to a QAction
      void Widget::runProcess()
      {
          QString sh = qgetenv("SHELL");
          process.setProgram(sh);
          process.setArguments(QStringList() << "-i");
          process.start();
      
          process.write("ls"); // first test
          // process.execute("ls"); // second test
      
          process.closeWriteChannel();
      }
      
      // slot connected to QProcess::finished
      void Widget::readOutput()
      {
          plainTextEdit->appendPlainText("readOutput");
          plainTextEdit->appendPlainText(process.readAllStandardError());
          plainTextEdit->appendPlainText(process.readAllStandardOutput());
      }
      

      In the first test QProcess::readAllStandardOutput() gives me the string "readOutput" and the listing of the current working directory in the plainTextEdit.

      For the second test I changed the following in Widget::runProcess():

          // process.write("ls"); // first test
          process.execute("ls"); // second test
      

      In the second test readyReadStandardOutput() is not emitted and the listing of the current working directory is show in the Application Output pane in QtCreator.

      I expected the output forwarded to the defined QProcess process, but it seems to be forwarded to the main application. Any ideas how I can get it in the calling QProcess process?

      J 1 Reply Last reply 24 Apr 2017, 09:46
      0
      • J Jan-Willem
        24 Apr 2017, 08:56

        @SGaist

        I made a simple example.

        // in constructor
        connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
        
        // slot connected to a QAction
        void Widget::runProcess()
        {
            QString sh = qgetenv("SHELL");
            process.setProgram(sh);
            process.setArguments(QStringList() << "-i");
            process.start();
        
            process.write("ls"); // first test
            // process.execute("ls"); // second test
        
            process.closeWriteChannel();
        }
        
        // slot connected to QProcess::finished
        void Widget::readOutput()
        {
            plainTextEdit->appendPlainText("readOutput");
            plainTextEdit->appendPlainText(process.readAllStandardError());
            plainTextEdit->appendPlainText(process.readAllStandardOutput());
        }
        

        In the first test QProcess::readAllStandardOutput() gives me the string "readOutput" and the listing of the current working directory in the plainTextEdit.

        For the second test I changed the following in Widget::runProcess():

            // process.write("ls"); // first test
            process.execute("ls"); // second test
        

        In the second test readyReadStandardOutput() is not emitted and the listing of the current working directory is show in the Application Output pane in QtCreator.

        I expected the output forwarded to the defined QProcess process, but it seems to be forwarded to the main application. Any ideas how I can get it in the calling QProcess process?

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 24 Apr 2017, 09:46 last edited by jsulm
        #4

        @Jan-Willem execute() is a static method! It is not related to your QProcess instance which you connected to your slot.
        You should replace

        process.setProgram(sh);
        

        with

        process.setProgram("ls");
        

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • J Offline
          J Offline
          Jan-Willem
          wrote on 24 Apr 2017, 14:15 last edited by
          #5

          @jsulm thanks for the clarification. The I have interpreted the use of execute() wrong.
          I know

          process.setProgram("ls");
          

          works. But I was trying to create a bash-session because of the variables defined in .bashrc.
          The output of the QProcess seems to be only available after the QProcess is finished. Consider this:

          process.setProgram("/bin/bash");
          process.start();
          process.write("pwd\n");
          process.write("cd ..\n");
          process.write("pwd");
          

          This gives the desired result, but the output is received only when the QProcess is finished. And then the bash-session is closed, so the result of cd is not there anymore.
          You see my problem? I can't seem to find a way around it.

          J 1 Reply Last reply 25 Apr 2017, 05:18
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 24 Apr 2017, 21:31 last edited by
            #6

            What exactly do you want to do with your serie of commands ?

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

            1 Reply Last reply
            0
            • J Jan-Willem
              24 Apr 2017, 14:15

              @jsulm thanks for the clarification. The I have interpreted the use of execute() wrong.
              I know

              process.setProgram("ls");
              

              works. But I was trying to create a bash-session because of the variables defined in .bashrc.
              The output of the QProcess seems to be only available after the QProcess is finished. Consider this:

              process.setProgram("/bin/bash");
              process.start();
              process.write("pwd\n");
              process.write("cd ..\n");
              process.write("pwd");
              

              This gives the desired result, but the output is received only when the QProcess is finished. And then the bash-session is closed, so the result of cd is not there anymore.
              You see my problem? I can't seem to find a way around it.

              J Offline
              J Offline
              jsulm
              Lifetime Qt Champion
              wrote on 25 Apr 2017, 05:18 last edited by jsulm
              #7

              @Jan-Willem Maybe you should do

              process.write("cd ..\n");
              process.write("pwd");
              

              after you got the output of the first pwd? Because currently you're flooding the shell with commands without waiting for them to finish.

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • J Offline
                J Offline
                Jan-Willem
                wrote on 25 Apr 2017, 09:48 last edited by
                #8

                @SGaist I'm experimenting with building a simple terminal window. The series of commands are only for testing. It could be any command for that matter.
                @jsulm Thanks, I suspected that. But the output never comes, unless I close the writingchannel or what for the process to finish.

                If I write:

                process.write("pwd\n");
                process.write("ls\n");
                process.write("pwd\n");
                

                it works as expected. The output after each step is shown. cmd does not generate output, but the result is also not shown on the last call of pwd.

                When I create a custom object through which the process is started and then connect it to a Q(Plain)TextEdit, then everything seems to work. I'm trying to understand the reason why.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 25 Apr 2017, 09:58 last edited by
                  #9

                  Do you have something like Konsole in mind ?

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

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    Jan-Willem
                    wrote on 25 Apr 2017, 11:41 last edited by
                    #10

                    Yes, but much more simple.
                    I have looked into that code and from a derived project QTermWidget.

                    It seems I now have a working solution, but I try to understand why this works.

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      Jan-Willem
                      wrote on 26 Apr 2017, 07:22 last edited by
                      #11

                      I have started from scratch to see what my problem actually was, but I wasn't able to reproduce it.
                      I probably got lost somewhere in my code.

                      Well, below is the working code for the curious.

                      @SGaist @jsulm Thanks for your help!

                      Widget::Widget(QWidget *parent)
                          : QWidget(parent)
                      {
                          QPlainTextEdit *plainTextEdit = new QPlainTextEdit(this);
                          plainTextEdit->setReadOnly(true);
                      
                          QLineEdit *lineEdit = new QLineEdit(this);
                          lineEdit->setClearButtonEnabled(true);
                      
                          QVBoxLayout *layout = new QVBoxLayout;
                          layout->addWidget(plainTextEdit);
                          layout->addWidget(lineEdit);
                          setLayout(layout);
                      
                          connect(&process, &QProcess::readyReadStandardOutput, [=](){ plainTextEdit->appendPlainText(process.readAllStandardOutput()); });
                          connect(&process, &QProcess::readyReadStandardError, [=](){ plainTextEdit->appendPlainText(process.readAllStandardError()); });
                          connect(&process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &Widget::close);
                          connect(lineEdit, &QLineEdit::returnPressed, [=](){ process.write(lineEdit->text().toLatin1() + "\n"); lineEdit->clear(); });
                      
                          process.start("sh");
                      }
                      
                      Widget::~Widget()
                      {
                          process.close();
                      }
                      
                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 26 Apr 2017, 11:47 last edited by
                        #12

                        If you have a recent enough version of Qt, you can use qOverload in place of static_cast. It will do the same but will be more readable.

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

                        1 Reply Last reply
                        1
                        • J Offline
                          J Offline
                          Jan-Willem
                          wrote on 27 Apr 2017, 19:41 last edited by
                          #13

                          @SGaist Good one! Though I had to use the C++11 version since C++14 is still in Debian Sid.

                          // C++11
                          connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &MainWindow::close);
                          

                          For those who want to know, this is the C++14-version:

                          // C++14
                          connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &MainWindow::close);
                          

                          Since the actual problem of this thread is solved, I will mark this thread as solved tomorrow. In the mean time comments on the above code can be made.

                          1 Reply Last reply
                          2

                          11/13

                          26 Apr 2017, 07:22

                          • Login

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