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 9 Feb 2024, 23:17 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 10 Feb 2024, 15:36
    0
    • A Anonymous_Banned275
      9 Feb 2024, 23:17

      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 10 Feb 2024, 15:36 last edited by Anonymous_Banned275 2 Oct 2024, 15:39
      #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;
                              }
      
      
      J A K T 4 Replies Last reply 10 Feb 2024, 15:47
      0
      • A Anonymous_Banned275
        10 Feb 2024, 15:36

        @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;
                                }
        
        
        J Offline
        J Offline
        JonB
        wrote on 10 Feb 2024, 15:47 last edited by JonB 2 Oct 2024, 15:48
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • A Anonymous_Banned275
          10 Feb 2024, 15:36

          @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;
                                  }
          
          
          A Offline
          A Offline
          Axel Spoerl
          Moderators
          wrote on 11 Feb 2024, 12:07 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
            10 Feb 2024, 15:36

            @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;
                                    }
            
            
            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 11 Feb 2024, 16:18 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
              10 Feb 2024, 15:36

              @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;
                                      }
              
              
              T Offline
              T Offline
              TomZ
              wrote on 11 Feb 2024, 19:26 last edited by TomZ 2 Nov 2024, 19:28
              #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 11 Feb 2024, 19:38
              2
              • T TomZ
                11 Feb 2024, 19:26

                @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 11 Feb 2024, 19:38 last edited by Anonymous_Banned275 2 Nov 2024, 19:47
                #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.

                T 1 Reply Last reply 14 Feb 2024, 16:21
                0
                • A Anonymous_Banned275
                  11 Feb 2024, 19:38

                  @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.

                  T Offline
                  T Offline
                  TomZ
                  wrote on 14 Feb 2024, 16:21 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 14 Feb 2024, 20:59
                  0
                  • T TomZ
                    14 Feb 2024, 16:21

                    @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 14 Feb 2024, 20:59 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 ?

                    J A 2 Replies Last reply 14 Feb 2024, 22:13
                    0
                    • A Anonymous_Banned275
                      14 Feb 2024, 20:59

                      @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 ?

                      J Offline
                      J Offline
                      JonB
                      wrote on 14 Feb 2024, 22:13 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
                      • K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 14 Feb 2024, 23:17 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
                          14 Feb 2024, 20:59

                          @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 ?

                          A Offline
                          A Offline
                          Axel Spoerl
                          Moderators
                          wrote on 15 Feb 2024, 22:58 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
                          • J Offline
                            J Offline
                            JonB
                            wrote on 16 Feb 2024, 09:50 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 17 Feb 2024, 02:22
                            2
                            • J JonB
                              16 Feb 2024, 09:50

                              @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 17 Feb 2024, 02:22 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"?

                              J 1 Reply Last reply 17 Feb 2024, 08:48
                              0
                              • A Anonymous_Banned275
                                17 Feb 2024, 02:22

                                @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"?

                                J Offline
                                J Offline
                                JonB
                                wrote on 17 Feb 2024, 08:48 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

                                8/15

                                14 Feb 2024, 16:21

                                • Login

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