Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. How to make QProcess "interactive" ?

How to make QProcess "interactive" ?

Scheduled Pinned Locked Moved Unsolved C++ Gurus
15 Posts 5 Posters 2.2k 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.
  • A Offline
    A Offline
    Anonymous_Banned275
    wrote on last edited by
    #1

    The attached function reads QProcess "standard " output... BUT won't read response from "sudo ". , hence it is not useful for "interactive" use.

    Can it be modified for interactive usage ?

    void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                            {
    
                                text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                ui->textEdit_2->append(text);
                                text  = "sudo ls " ;
    
                                QProcess *process;
                                process = new QProcess();
                                //process->start("hcitool", QStringList() << "dev"); OK 
                                process->start("sudo", QStringList() << "lsusb");  FAILS 
                                if(process->Running)
                                {
                                    if(process->waitForReadyRead() && process->waitForFinished())
                                    {
                                        // qDebug() << process->StandardOutput;
                                        result = process->readAllStandardOutput();
                                        qDebug() << result;
                                    }
                                    else
                                    {
                                        qDebug()<< "FAILED !!";
                                    }
                                }
                                else
                                {
                                    qDebug()<< "FAILED process did not start!";
                                }
                                return;
                            }
    
    
    A 1 Reply Last reply
    0
    • A Anonymous_Banned275

      The attached function reads QProcess "standard " output... BUT won't read response from "sudo ". , hence it is not useful for "interactive" use.

      Can it be modified for interactive usage ?

      void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                              {
      
                                  text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                  ui->textEdit_2->append(text);
                                  text  = "sudo ls " ;
      
                                  QProcess *process;
                                  process = new QProcess();
                                  //process->start("hcitool", QStringList() << "dev"); OK 
                                  process->start("sudo", QStringList() << "lsusb");  FAILS 
                                  if(process->Running)
                                  {
                                      if(process->waitForReadyRead() && process->waitForFinished())
                                      {
                                          // qDebug() << process->StandardOutput;
                                          result = process->readAllStandardOutput();
                                          qDebug() << result;
                                      }
                                      else
                                      {
                                          qDebug()<< "FAILED !!";
                                      }
                                  }
                                  else
                                  {
                                      qDebug()<< "FAILED process did not start!";
                                  }
                                  return;
                              }
      
      
      A Offline
      A Offline
      Anonymous_Banned275
      wrote on last edited by Anonymous_Banned275
      #2

      @AnneRanch I would like to "rephrase" my question

      why it this code
      starts Linux "terminal" .and prints correct response

      and FAILS to detect it ?

                          void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                              {
      
                                  text = " DEBUG terminal.... ";
                                  text = Q_FUNC_INFO;
                                  text += "  @ line  ";
                                  text += QString::number(__LINE__);
                                  ui->textEdit_2->append(text); // debug
                                  qDebug()<<text;
                                  //text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                  //''ui->textEdit_2->append(text);
                                  // text  = "sudo ls " ;
      
                                  QProcess *process;
                                  process = new QProcess();
                                  //process->start("hcitool", QStringList() << "dev");
                                  process->start("/usr/bin/gnome-terminal", QStringList() << "lsusb");
                                  if(process->Running)
                                  {
                                      text = "process->Running  OK ";
                                      ui->textEdit_2->append(text);
                                      qDebug() << text;
      
      **THIS CODE FAILS** 
                                      if(process->waitForReadyRead())
                                      {
                                          text = "process->waitForReadyRead()  OK ";
                                          ui->textEdit_2->append(text);
                                          qDebug() << text;
                                      }
                                      else
                                      {
                                          text = "process->waitForReadyRead()  FAILED  ";
                                          ui->textEdit_2->append(text);
                                          qDebug() << text;
                                      }
                                      // what is fail value ??
                                      if(process->waitForReadyRead() && process->waitForFinished())
                                      {
                                          // qDebug() << process->StandardOutput;
                                          result = process->readAllStandardOutput();
                                          qDebug() << result;
                                          ui->textEdit_2->append(result);
                                      }
                                      else
                                      {
                                          qDebug()<< "FAILED process->waitForReadyRead() && process->waitForFinished()";
                                          process->write("q\n");
                                          if(process->waitForReadyRead() && process->waitForFinished())
                                          {
                                              // qDebug() << process->StandardOutput;
                                              result = process->readAllStandardOutput();
                                              qDebug() << result;
                                              ui->textEdit_2->append(result);
                                          }
                                          else
                                          {
                                              qDebug()<< "FAILED AFTER WRITE process->waitForReadyRead() && process->waitForFinished()";
                                          }
      
                                      }
      
                                  }
                                  else
                                  {
                                      qDebug()<< "FAILED process did not start!!!!!!!!!!!!!!!!!!!!!!!!!!!";
                                  }
                                  return;
                              }
      
      
      JonBJ Axel SpoerlA kshegunovK TomZT 4 Replies Last reply
      0
      • A Anonymous_Banned275

        @AnneRanch I would like to "rephrase" my question

        why it this code
        starts Linux "terminal" .and prints correct response

        and FAILS to detect it ?

                            void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                                {
        
                                    text = " DEBUG terminal.... ";
                                    text = Q_FUNC_INFO;
                                    text += "  @ line  ";
                                    text += QString::number(__LINE__);
                                    ui->textEdit_2->append(text); // debug
                                    qDebug()<<text;
                                    //text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                    //''ui->textEdit_2->append(text);
                                    // text  = "sudo ls " ;
        
                                    QProcess *process;
                                    process = new QProcess();
                                    //process->start("hcitool", QStringList() << "dev");
                                    process->start("/usr/bin/gnome-terminal", QStringList() << "lsusb");
                                    if(process->Running)
                                    {
                                        text = "process->Running  OK ";
                                        ui->textEdit_2->append(text);
                                        qDebug() << text;
        
        **THIS CODE FAILS** 
                                        if(process->waitForReadyRead())
                                        {
                                            text = "process->waitForReadyRead()  OK ";
                                            ui->textEdit_2->append(text);
                                            qDebug() << text;
                                        }
                                        else
                                        {
                                            text = "process->waitForReadyRead()  FAILED  ";
                                            ui->textEdit_2->append(text);
                                            qDebug() << text;
                                        }
                                        // what is fail value ??
                                        if(process->waitForReadyRead() && process->waitForFinished())
                                        {
                                            // qDebug() << process->StandardOutput;
                                            result = process->readAllStandardOutput();
                                            qDebug() << result;
                                            ui->textEdit_2->append(result);
                                        }
                                        else
                                        {
                                            qDebug()<< "FAILED process->waitForReadyRead() && process->waitForFinished()";
                                            process->write("q\n");
                                            if(process->waitForReadyRead() && process->waitForFinished())
                                            {
                                                // qDebug() << process->StandardOutput;
                                                result = process->readAllStandardOutput();
                                                qDebug() << result;
                                                ui->textEdit_2->append(result);
                                            }
                                            else
                                            {
                                                qDebug()<< "FAILED AFTER WRITE process->waitForReadyRead() && process->waitForFinished()";
                                            }
        
                                        }
        
                                    }
                                    else
                                    {
                                        qDebug()<< "FAILED process did not start!!!!!!!!!!!!!!!!!!!!!!!!!!!";
                                    }
                                    return;
                                }
        
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • A Anonymous_Banned275

          @AnneRanch I would like to "rephrase" my question

          why it this code
          starts Linux "terminal" .and prints correct response

          and FAILS to detect it ?

                              void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                                  {
          
                                      text = " DEBUG terminal.... ";
                                      text = Q_FUNC_INFO;
                                      text += "  @ line  ";
                                      text += QString::number(__LINE__);
                                      ui->textEdit_2->append(text); // debug
                                      qDebug()<<text;
                                      //text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                      //''ui->textEdit_2->append(text);
                                      // text  = "sudo ls " ;
          
                                      QProcess *process;
                                      process = new QProcess();
                                      //process->start("hcitool", QStringList() << "dev");
                                      process->start("/usr/bin/gnome-terminal", QStringList() << "lsusb");
                                      if(process->Running)
                                      {
                                          text = "process->Running  OK ";
                                          ui->textEdit_2->append(text);
                                          qDebug() << text;
          
          **THIS CODE FAILS** 
                                          if(process->waitForReadyRead())
                                          {
                                              text = "process->waitForReadyRead()  OK ";
                                              ui->textEdit_2->append(text);
                                              qDebug() << text;
                                          }
                                          else
                                          {
                                              text = "process->waitForReadyRead()  FAILED  ";
                                              ui->textEdit_2->append(text);
                                              qDebug() << text;
                                          }
                                          // what is fail value ??
                                          if(process->waitForReadyRead() && process->waitForFinished())
                                          {
                                              // qDebug() << process->StandardOutput;
                                              result = process->readAllStandardOutput();
                                              qDebug() << result;
                                              ui->textEdit_2->append(result);
                                          }
                                          else
                                          {
                                              qDebug()<< "FAILED process->waitForReadyRead() && process->waitForFinished()";
                                              process->write("q\n");
                                              if(process->waitForReadyRead() && process->waitForFinished())
                                              {
                                                  // qDebug() << process->StandardOutput;
                                                  result = process->readAllStandardOutput();
                                                  qDebug() << result;
                                                  ui->textEdit_2->append(result);
                                              }
                                              else
                                              {
                                                  qDebug()<< "FAILED AFTER WRITE process->waitForReadyRead() && process->waitForFinished()";
                                              }
          
                                          }
          
                                      }
                                      else
                                      {
                                          qDebug()<< "FAILED process did not start!!!!!!!!!!!!!!!!!!!!!!!!!!!";
                                      }
                                      return;
                                  }
          
          
          Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote on last edited by
          #4

          @AnneRanch
          QProcess is not designed to be interactive. Neither is sudo designed to be used non interactive. You can work around the latter by adding the user to /etc/sudoers.
          If you want to read console input, have a look at this repository: https://github.com/juangburgos/QConsoleListener

          I think it does what you want.

          Software Engineer
          The Qt Company, Oslo

          1 Reply Last reply
          2
          • A Anonymous_Banned275

            @AnneRanch I would like to "rephrase" my question

            why it this code
            starts Linux "terminal" .and prints correct response

            and FAILS to detect it ?

                                void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                                    {
            
                                        text = " DEBUG terminal.... ";
                                        text = Q_FUNC_INFO;
                                        text += "  @ line  ";
                                        text += QString::number(__LINE__);
                                        ui->textEdit_2->append(text); // debug
                                        qDebug()<<text;
                                        //text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                        //''ui->textEdit_2->append(text);
                                        // text  = "sudo ls " ;
            
                                        QProcess *process;
                                        process = new QProcess();
                                        //process->start("hcitool", QStringList() << "dev");
                                        process->start("/usr/bin/gnome-terminal", QStringList() << "lsusb");
                                        if(process->Running)
                                        {
                                            text = "process->Running  OK ";
                                            ui->textEdit_2->append(text);
                                            qDebug() << text;
            
            **THIS CODE FAILS** 
                                            if(process->waitForReadyRead())
                                            {
                                                text = "process->waitForReadyRead()  OK ";
                                                ui->textEdit_2->append(text);
                                                qDebug() << text;
                                            }
                                            else
                                            {
                                                text = "process->waitForReadyRead()  FAILED  ";
                                                ui->textEdit_2->append(text);
                                                qDebug() << text;
                                            }
                                            // what is fail value ??
                                            if(process->waitForReadyRead() && process->waitForFinished())
                                            {
                                                // qDebug() << process->StandardOutput;
                                                result = process->readAllStandardOutput();
                                                qDebug() << result;
                                                ui->textEdit_2->append(result);
                                            }
                                            else
                                            {
                                                qDebug()<< "FAILED process->waitForReadyRead() && process->waitForFinished()";
                                                process->write("q\n");
                                                if(process->waitForReadyRead() && process->waitForFinished())
                                                {
                                                    // qDebug() << process->StandardOutput;
                                                    result = process->readAllStandardOutput();
                                                    qDebug() << result;
                                                    ui->textEdit_2->append(result);
                                                }
                                                else
                                                {
                                                    qDebug()<< "FAILED AFTER WRITE process->waitForReadyRead() && process->waitForFinished()";
                                                }
            
                                            }
            
                                        }
                                        else
                                        {
                                            qDebug()<< "FAILED process did not start!!!!!!!!!!!!!!!!!!!!!!!!!!!";
                                        }
                                        return;
                                    }
            
            
            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            Alternatively pipe whatever is that you want to run as root through pkexec, which is a small utility that prompts for root password before executing what you pass on the command line (i.e. command line arguments).

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            1
            • A Anonymous_Banned275

              @AnneRanch I would like to "rephrase" my question

              why it this code
              starts Linux "terminal" .and prints correct response

              and FAILS to detect it ?

                                  void MainWindow_Bluewtoothctl_Dialog::on_pushButton_21_clicked()
                                      {
              
                                          text = " DEBUG terminal.... ";
                                          text = Q_FUNC_INFO;
                                          text += "  @ line  ";
                                          text += QString::number(__LINE__);
                                          ui->textEdit_2->append(text); // debug
                                          qDebug()<<text;
                                          //text = " DEBUG  TEST  hcitool info 98:D3:31:F8:39:33";
                                          //''ui->textEdit_2->append(text);
                                          // text  = "sudo ls " ;
              
                                          QProcess *process;
                                          process = new QProcess();
                                          //process->start("hcitool", QStringList() << "dev");
                                          process->start("/usr/bin/gnome-terminal", QStringList() << "lsusb");
                                          if(process->Running)
                                          {
                                              text = "process->Running  OK ";
                                              ui->textEdit_2->append(text);
                                              qDebug() << text;
              
              **THIS CODE FAILS** 
                                              if(process->waitForReadyRead())
                                              {
                                                  text = "process->waitForReadyRead()  OK ";
                                                  ui->textEdit_2->append(text);
                                                  qDebug() << text;
                                              }
                                              else
                                              {
                                                  text = "process->waitForReadyRead()  FAILED  ";
                                                  ui->textEdit_2->append(text);
                                                  qDebug() << text;
                                              }
                                              // what is fail value ??
                                              if(process->waitForReadyRead() && process->waitForFinished())
                                              {
                                                  // qDebug() << process->StandardOutput;
                                                  result = process->readAllStandardOutput();
                                                  qDebug() << result;
                                                  ui->textEdit_2->append(result);
                                              }
                                              else
                                              {
                                                  qDebug()<< "FAILED process->waitForReadyRead() && process->waitForFinished()";
                                                  process->write("q\n");
                                                  if(process->waitForReadyRead() && process->waitForFinished())
                                                  {
                                                      // qDebug() << process->StandardOutput;
                                                      result = process->readAllStandardOutput();
                                                      qDebug() << result;
                                                      ui->textEdit_2->append(result);
                                                  }
                                                  else
                                                  {
                                                      qDebug()<< "FAILED AFTER WRITE process->waitForReadyRead() && process->waitForFinished()";
                                                  }
              
                                              }
              
                                          }
                                          else
                                          {
                                              qDebug()<< "FAILED process did not start!!!!!!!!!!!!!!!!!!!!!!!!!!!";
                                          }
                                          return;
                                      }
              
              
              TomZT Offline
              TomZT Offline
              TomZ
              wrote on last edited by TomZ
              #6

              @AnneRanch said in How to make QProcess "interactive" ?:

              why it this code

              frankly, there is more wrong with this code than correct. (I'm Dutch, sorry we're blunt).

              You've missed the async nature of Qt, for starters. You should NEVER call methods like "wait for" in a callback from the UI.

              As others indicated, sudo is specifically designed to not allow this. The structural solution is policyKit, as generally it's a bad approach to make a button press start an admin process.

              Which then leads to the point that QProcess is not meant for this kind of thing either. Good examples of QProcess are a front-end for Git that calls git commands behind the scenes. Bad examples are anything that requires any type of interaction. It's not impossible, just not a good idea.

              Bottom line; use policyKit, or its newer version polkit.

              A 1 Reply Last reply
              2
              • TomZT TomZ

                @AnneRanch said in How to make QProcess "interactive" ?:

                why it this code

                frankly, there is more wrong with this code than correct. (I'm Dutch, sorry we're blunt).

                You've missed the async nature of Qt, for starters. You should NEVER call methods like "wait for" in a callback from the UI.

                As others indicated, sudo is specifically designed to not allow this. The structural solution is policyKit, as generally it's a bad approach to make a button press start an admin process.

                Which then leads to the point that QProcess is not meant for this kind of thing either. Good examples of QProcess are a front-end for Git that calls git commands behind the scenes. Bad examples are anything that requires any type of interaction. It's not impossible, just not a good idea.

                Bottom line; use policyKit, or its newer version polkit.

                A Offline
                A Offline
                Anonymous_Banned275
                wrote on last edited by Anonymous_Banned275
                #7

                @TomZ OK, you can be blunt, but I cannot...
                Here it the minimal explanation for my need for interactive QProcess...I am writing Bluetooth application for my own use - hence I am not concerned about the use or misuse of "sudo'-- end of story.
                I started by using Qt Bluetooth code to find out it has "few holes" .. the main one - it does not always physically scan for devices - it uses RANDOM unknown data from past...

                So I switched to using fundamental Linux commands , hence I really need interactive code.

                I understand "interactive " can be done using output redirection or "native window"... and I am heading that direction.

                TomZT 1 Reply Last reply
                0
                • A Anonymous_Banned275

                  @TomZ OK, you can be blunt, but I cannot...
                  Here it the minimal explanation for my need for interactive QProcess...I am writing Bluetooth application for my own use - hence I am not concerned about the use or misuse of "sudo'-- end of story.
                  I started by using Qt Bluetooth code to find out it has "few holes" .. the main one - it does not always physically scan for devices - it uses RANDOM unknown data from past...

                  So I switched to using fundamental Linux commands , hence I really need interactive code.

                  I understand "interactive " can be done using output redirection or "native window"... and I am heading that direction.

                  TomZT Offline
                  TomZT Offline
                  TomZ
                  wrote on last edited by
                  #8

                  @AnneRanch thank you for taking my message in stride :-)

                  I just want to first up state that the reason I suggested to not use sudo interactively is not because I'm playing the responsible parent or anything.
                  The reason I'm saying this is because the sudo authors went out of their way to make it very hard to do this. Again, sudo and interactively..

                  If you need to use sudo, make sure you can do this non-interactively. Which means to do so passwordless for those commands you need executed as root.
                  You can get started with that here:
                  https://help.ubuntu.com/community/Sudoers


                  Now, you write your bluetooth app requires you to do things interactively, presumably with commandline tools. Not sure if I got that part. Things like lsusb don't require sudo, so your example didn't enlighten me.

                  As I wrote, you can make qprocess be interactive.

                  You want to write a class that owns it and work in async manner (using signals and slots) without any wait type of methods. Ideally your apps that run as root never touch stderr, which makes it much easier and you'll be able to find and use any type of QIODevice based tutorial on how to interactively send and receive data.

                  A 1 Reply Last reply
                  0
                  • TomZT TomZ

                    @AnneRanch thank you for taking my message in stride :-)

                    I just want to first up state that the reason I suggested to not use sudo interactively is not because I'm playing the responsible parent or anything.
                    The reason I'm saying this is because the sudo authors went out of their way to make it very hard to do this. Again, sudo and interactively..

                    If you need to use sudo, make sure you can do this non-interactively. Which means to do so passwordless for those commands you need executed as root.
                    You can get started with that here:
                    https://help.ubuntu.com/community/Sudoers


                    Now, you write your bluetooth app requires you to do things interactively, presumably with commandline tools. Not sure if I got that part. Things like lsusb don't require sudo, so your example didn't enlighten me.

                    As I wrote, you can make qprocess be interactive.

                    You want to write a class that owns it and work in async manner (using signals and slots) without any wait type of methods. Ideally your apps that run as root never touch stderr, which makes it much easier and you'll be able to find and use any type of QIODevice based tutorial on how to interactively send and receive data.

                    A Offline
                    A Offline
                    Anonymous_Banned275
                    wrote on last edited by
                    #9

                    @TomZ Thanks for reply.

                    Allow me to modify this discussion.

                    Here is my FULL TEST code.

                    MainWindow::MainWindow(QWidget *parent)
                        : QMainWindow(parent)
                        , ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                        QProcess *QP = new QProcess();
                        QP->start( "/usr/bin/gnome-terminal", QStringList() <<  "  lsusb ");
                        //QP->write("lsusb");
                    }
                    
                    MainWindow::~MainWindow()
                    {
                        delete ui;
                    }
                    
                    

                    here is FULL run output

                    bf631560-7f31-4dc8-92ad-f4d208f534dd-image.png

                    the "start" HAS option "lsusb" there is NO " sudo" required

                    AND there is no " lsusb" output

                    BUT I can input "lsusb" manually and get expected data .
                    however I desire to have interactive ( read/ write ) code.

                    PS the doc clearly states this is
                    how QPocess should work.

                    "The QProcess class is used to start external programs and to communicate with them."

                    The question remains - what is missing in code ?

                    JonBJ Axel SpoerlA 2 Replies Last reply
                    0
                    • A Anonymous_Banned275

                      @TomZ Thanks for reply.

                      Allow me to modify this discussion.

                      Here is my FULL TEST code.

                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                          QProcess *QP = new QProcess();
                          QP->start( "/usr/bin/gnome-terminal", QStringList() <<  "  lsusb ");
                          //QP->write("lsusb");
                      }
                      
                      MainWindow::~MainWindow()
                      {
                          delete ui;
                      }
                      
                      

                      here is FULL run output

                      bf631560-7f31-4dc8-92ad-f4d208f534dd-image.png

                      the "start" HAS option "lsusb" there is NO " sudo" required

                      AND there is no " lsusb" output

                      BUT I can input "lsusb" manually and get expected data .
                      however I desire to have interactive ( read/ write ) code.

                      PS the doc clearly states this is
                      how QPocess should work.

                      "The QProcess class is used to start external programs and to communicate with them."

                      The question remains - what is missing in code ?

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

                      @AnneRanch
                      Because it is not running lsusb? Your command is /usr/bin/gnome-terminal lsusb. I don't think that is right, did you try copying and pasting that onto a command line to test? If it's not right there it won;t be right from QProcess. From what I can see you might need any of these:

                      /usr/bin/gnome-terminal --command lsusb
                      /usr/bin/gnome-terminal --exec lsusb
                      /usr/bin/gnome-terminal -e lsusb
                      /usr/bin/gnome-terminal -x lsusb
                      /usr/bin/gnome-terminal -- lsusb
                      

                      Look at https://manpages.ubuntu.com/manpages/xenial/en/man1/gnome-terminal.1.html or try man gnome-terminal or gnome-terminal --help on your system.

                      1 Reply Last reply
                      0
                      • kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        @AnneRanch said in How to make QProcess "interactive" ?:

                        Here is my FULL TEST code.

                        ... your full test code doesn't read the standard output of the started process.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2
                        • A Anonymous_Banned275

                          @TomZ Thanks for reply.

                          Allow me to modify this discussion.

                          Here is my FULL TEST code.

                          MainWindow::MainWindow(QWidget *parent)
                              : QMainWindow(parent)
                              , ui(new Ui::MainWindow)
                          {
                              ui->setupUi(this);
                              QProcess *QP = new QProcess();
                              QP->start( "/usr/bin/gnome-terminal", QStringList() <<  "  lsusb ");
                              //QP->write("lsusb");
                          }
                          
                          MainWindow::~MainWindow()
                          {
                              delete ui;
                          }
                          
                          

                          here is FULL run output

                          bf631560-7f31-4dc8-92ad-f4d208f534dd-image.png

                          the "start" HAS option "lsusb" there is NO " sudo" required

                          AND there is no " lsusb" output

                          BUT I can input "lsusb" manually and get expected data .
                          however I desire to have interactive ( read/ write ) code.

                          PS the doc clearly states this is
                          how QPocess should work.

                          "The QProcess class is used to start external programs and to communicate with them."

                          The question remains - what is missing in code ?

                          Axel SpoerlA Offline
                          Axel SpoerlA Offline
                          Axel Spoerl
                          Moderators
                          wrote on last edited by
                          #12

                          @AnneRanch said in How to make QProcess "interactive" ?:

                          "The QProcess class is used to start external programs and to communicate with them."

                          You misinterpret the documentation. QProcessstarts external programs and communicates with them. What you want to do, is to start an external program, let the user communicate with it in a defined manner and read back the result. As said before: Not possible in Qt and I wouldn't know of any well known tool, that is suitable for such a contained user interaction.

                          And just on a side note: Your full test code leaks a QProcess - an eye catching antipattern.

                          Software Engineer
                          The Qt Company, Oslo

                          1 Reply Last reply
                          1
                          • JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @kshegunov , @Axel-Spoerl
                            Your comments are, of course, quite correct, However, I would remind you and OP that, as per my first reply, the command being issued is /usr/bin/gnome-terminal lsusb. This is an incorrect command line for /usr/bin/gnome-terminal. The trailing lsusb is simply ignored in this case, it is not run, and instead an interactive terminal is simply opened, just as the screenshot shows.

                            Furthermore, as also discussed in the past, a terminal such as /usr/bin/gnome-terminal (with or without the correct arguments to cause it to run a command) simply does not produce any output on the stdout, so nothing can be read from QProcess from it. Consider the following:

                            gnome-terminal -- find / -print
                            

                            [We have to call something which produces voluminous output, else the terminal window opens, runs the command and closes so quickly that you do not see anything.] You see the output running by in the opened terminal, till it concludes. Now try

                            jon@ubuntu-22:~$ gnome-terminal -- find / -print > output
                            jon@ubuntu-22:~$ ls -l output
                            -rw-rw-r-- 1 jon jon 0 Feb 16 09:47 output
                            

                            Same behaviour as without the attempted redirection: the output appears in the opened terminal window, and at the end nothing has been written into output file, i.e. redirection from calling program captures nothing.

                            Terminals such as gnome-terminal (and the others, e..g xterm) start by creating a window and attaching their stdout to that (pseudo-tty). You cannot get at their output via the normal redirection which would work on a command without running it in a terminal. I have said this to OP in the past for just this question.

                            A 1 Reply Last reply
                            2
                            • JonBJ JonB

                              @kshegunov , @Axel-Spoerl
                              Your comments are, of course, quite correct, However, I would remind you and OP that, as per my first reply, the command being issued is /usr/bin/gnome-terminal lsusb. This is an incorrect command line for /usr/bin/gnome-terminal. The trailing lsusb is simply ignored in this case, it is not run, and instead an interactive terminal is simply opened, just as the screenshot shows.

                              Furthermore, as also discussed in the past, a terminal such as /usr/bin/gnome-terminal (with or without the correct arguments to cause it to run a command) simply does not produce any output on the stdout, so nothing can be read from QProcess from it. Consider the following:

                              gnome-terminal -- find / -print
                              

                              [We have to call something which produces voluminous output, else the terminal window opens, runs the command and closes so quickly that you do not see anything.] You see the output running by in the opened terminal, till it concludes. Now try

                              jon@ubuntu-22:~$ gnome-terminal -- find / -print > output
                              jon@ubuntu-22:~$ ls -l output
                              -rw-rw-r-- 1 jon jon 0 Feb 16 09:47 output
                              

                              Same behaviour as without the attempted redirection: the output appears in the opened terminal window, and at the end nothing has been written into output file, i.e. redirection from calling program captures nothing.

                              Terminals such as gnome-terminal (and the others, e..g xterm) start by creating a window and attaching their stdout to that (pseudo-tty). You cannot get at their output via the normal redirection which would work on a command without running it in a terminal. I have said this to OP in the past for just this question.

                              A Offline
                              A Offline
                              Anonymous_Banned275
                              wrote on last edited by
                              #14

                              @JonB said in How to make QProcess "interactive" ?:

                              the output appears in the opened terminal window,

                              Please explain the above - if it is is NOT "'stdxx" what is it ?

                              ... and why QProcess does not pass the "lsusb" at all?
                              is it not passed as an "option"?

                              JonBJ 1 Reply Last reply
                              0
                              • A Anonymous_Banned275

                                @JonB said in How to make QProcess "interactive" ?:

                                the output appears in the opened terminal window,

                                Please explain the above - if it is is NOT "'stdxx" what is it ?

                                ... and why QProcess does not pass the "lsusb" at all?
                                is it not passed as an "option"?

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

                                @AnneRanch
                                Anne, I explained both of these above. You ask for clarification but what can I say further to what In have written? Summary:

                                • The command you are issuing, gnome-terminal lsusb, is not and never has been the correct syntax to ask gnome-terminal to run a command. It ignores the lsusb completely and simply runs gnome-terminal. So you see an interactive terminal window sitting there instead. For Ubuntu the command should be gnome-terminal -- lsusb. That will open the window, run lsusb and close the window when that finishes. Which happens so quickly in milliseconds that you simply won't see anything, the window will open and close faster than you can see. Which is why I said if you were to run gnome-terminal -- find / -print you will get to see what actually is happening. You can try these outside of your Qt program from a terminal.

                                • If you invoke gnome-terminal, or any other "terminal" such as xterm, to run a command (such as lsusb) the terminal will attach its stdout to the window it opens. That means no matter what your calling program --- a Linux shell or a Qt application --- it will not receive or be able to access any output the command (lsusb or whatever) produces e.g. on its stdout. That will go to the terminal window and cannot be seen by the calling application.

                                As per when we discussed this a year or two ago and I said then, if you want to be able to read back the output from, say, lsusb you must run it directly (as the command you tell QProcess to start) and not invoke any gnome-terminal or xterm or other terminal to run it.

                                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