Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. text append waits until hcitoo scan is finished
Forum Updated to NodeBB v4.3 + New Features

text append waits until hcitoo scan is finished

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 6 Posters 2.4k Views 2 Watching
  • 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.
  • C Offline
    C Offline
    ChrisW67
    wrote on last edited by
    #12

    The blocking behaviour of hcitool is not a Qt problem. hcitool has options for controlling timeouts (at least the Bluez source code I am looking at does). However, you seem to be running something on Windows, so I have no idea what your hcittool really is.

    Is there a reason that you are not using the Qt Bluetooth support?

    A 1 Reply Last reply
    0
    • JamieghosalJ Offline
      JamieghosalJ Offline
      Jamieghosal
      wrote on last edited by
      #13

      I am also facing some kind of erroneous things which I am sharing along with btconnect.h file -
      This is my btconnect.h file

      #ifndef BTCONNECT_H
      #define BTCONNECT_H

      #include "scandialog.h"

      namespace Ui {
      class BTConnect;
      }

      class BTConnect : public QWidget
      {
      Q_OBJECT

      public:
      explicit BTConnect(QWidget *parent = 0);
      ~BTConnect();

      private slots:
      void on_ScanButton_clicked();

      void ScanBTDevices();
      
      //some slots here
      
      void ScanDialogShow();
      
      void ScanDialogClose();
      

      public slots:
      //some slots here

      private:
      Ui::BTConnect *ui;

      QProcess BTscan_Process;
      
      scanDialog *scan;
      

      };

      #endif // BTCONNECT_H
      btconnect.cpp

      BTConnect::BTConnect(QWidget *parent) :
      QWidget(parent),
      ui(new Ui::BTConnect)
      {
      //set the userinterface as BTConnect.ui
      ui->setupUi(this);

      scan = new scanDialog(this);
      

      }

      void BTConnect::ScanDialogShow()
      {
      scan->show();
      }

      void BTConnect::ScanDialogClose()
      {
      scan->close();
      }

      void BTConnect::ScanBTDevices()
      {
      ScanDialogShow();

      //Command to scan nearby bluetooth devices
      //"hcitool scan"
      QString cmd("hcitool scan");
      
      //start the process
      BTscan_Process.start(cmd);
      
      //Wait for the processs to finish with a timeout of 20 seconds
      if(BTscan_Process.waitForFinished(20000))
      {
          //Clear the list widget
          this->ui->listWidget->clear();
      
          //Read the command line output and store it in QString out
          QString out(BTscan_Process.readAllStandardOutput());
      
          //Split the QString every new line and save theve in a QStringList
          QStringList OutSplit = out.split("\n");
      
          //Parse the QStringList in btCellsParser
          btCellsParser cp(OutSplit);
      
          for(unsigned int i = 0; i<cp.count(); i++)
          {
             //writing in listwidget
          }
      
      }
      
      ScanDialogClose();
      

      }

      void BTConnect::on_ScanButton_clicked()
      {
      //Scan for available nearby bluetooth devices
      ScanBTDevices();
      }
      if I use the above code, the qdialog scandialog does open when the process begins and closes when the data is loaded in qlistwidget, but the contents of qdialog scandialog are not displayed. If I were to change show() to exec(), the contents will be shown but the QProcess does not run until the dialog is closed.

      I want the dialog to open when the Qprocess starts and close when the qlistwidget is loaded with data from the scan. And I want the contents of scandialog to be displayed. It has two labels. One with .GIF file and another with text saying scanning.

      Any help is appreciated.

      Answer - 1
      0 arrow_circle_up 0 arrow_circle_down
      The problem is that QDialog::exec and QProcess::waitForFinished functions block event loop. Never ever block event loop. So you just need to do things more asynchronously.

      QProcess class can be handled asynchronously using signals like readReadStandardOutput. And QDialog can be shown asynchronously using open slot.

      The example:

      void ScanBTDevices() {
      // Open dialog when process is started
      connect(process, SIGNAL(started()), dialog, SLOT(open()));

      // Read standard output asynchronously
      connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyRead()));
      
      // Start process asynchronously (for example I use recursive ls)
      process->start("ls -R /");
      

      }

      void onReadyRead() {
      // Write to list widget
      dialog->appendText(QString(process->readAllStandardOutput()));
      }
      The data will be appended to the dialog during generating by process. Also using QProcess::finished signal and you can close the dialog.

      by *
      Answer - 2 verified
      0 arrow_circle_up 0 arrow_circle_down
      you never return to the event loop when you do show (because of waitForFinished) and you never continue to the processing code when you do exec

      instead of the waitForFinished you should connect to the finished signal and handle it there and use a single shot timer that will cancel it:

      void BTConnect::on_BTscanFinished()//new slot
      {
      //Clear the list widget
      this->ui->listWidget->clear();

      //Read the command line output and store it in QString out
      QString out(BTscan_Process.readAllStandardOutput());
      

      After doing all of this I basically stuck on virtual onboarding software.
      //Split the QString every new line and save theve in a QStringList
      QStringList OutSplit = out.split("\n");

      //Parse the QStringList in btCellsParser
      btCellsParser cp(OutSplit);
      
      for(unsigned int i = 0; i<cp.count(); i++)
      {
         //writing in listwidget
      }
      ScanDialogClose();
      

      }

      void BTConnect::ScanBTDevices()
      {
      ScanDialogShow();

      //Command to scan nearby bluetooth devices
      //"hcitool scan"
      QString cmd("hcitool scan");
      
      //start the process
      connect(BTscan_Process, SIGNAL(finished()), this, SLOT(on_BTscanFinished()));
      BTscan_Process.start(cmd);
      QTimer::singleShot(20000, scan, SLOT(close()));
      

      }

      Hope this will properly help you.

      Exactlly software is a leading software and solutions provider specializing in ERP, HRMS, CRM and PMS. The company operates globally through its operations in India, UAE, Oman, Singapore and Malaysia.

      A 2 Replies Last reply
      0
      • JamieghosalJ Jamieghosal

        I am also facing some kind of erroneous things which I am sharing along with btconnect.h file -
        This is my btconnect.h file

        #ifndef BTCONNECT_H
        #define BTCONNECT_H

        #include "scandialog.h"

        namespace Ui {
        class BTConnect;
        }

        class BTConnect : public QWidget
        {
        Q_OBJECT

        public:
        explicit BTConnect(QWidget *parent = 0);
        ~BTConnect();

        private slots:
        void on_ScanButton_clicked();

        void ScanBTDevices();
        
        //some slots here
        
        void ScanDialogShow();
        
        void ScanDialogClose();
        

        public slots:
        //some slots here

        private:
        Ui::BTConnect *ui;

        QProcess BTscan_Process;
        
        scanDialog *scan;
        

        };

        #endif // BTCONNECT_H
        btconnect.cpp

        BTConnect::BTConnect(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::BTConnect)
        {
        //set the userinterface as BTConnect.ui
        ui->setupUi(this);

        scan = new scanDialog(this);
        

        }

        void BTConnect::ScanDialogShow()
        {
        scan->show();
        }

        void BTConnect::ScanDialogClose()
        {
        scan->close();
        }

        void BTConnect::ScanBTDevices()
        {
        ScanDialogShow();

        //Command to scan nearby bluetooth devices
        //"hcitool scan"
        QString cmd("hcitool scan");
        
        //start the process
        BTscan_Process.start(cmd);
        
        //Wait for the processs to finish with a timeout of 20 seconds
        if(BTscan_Process.waitForFinished(20000))
        {
            //Clear the list widget
            this->ui->listWidget->clear();
        
            //Read the command line output and store it in QString out
            QString out(BTscan_Process.readAllStandardOutput());
        
            //Split the QString every new line and save theve in a QStringList
            QStringList OutSplit = out.split("\n");
        
            //Parse the QStringList in btCellsParser
            btCellsParser cp(OutSplit);
        
            for(unsigned int i = 0; i<cp.count(); i++)
            {
               //writing in listwidget
            }
        
        }
        
        ScanDialogClose();
        

        }

        void BTConnect::on_ScanButton_clicked()
        {
        //Scan for available nearby bluetooth devices
        ScanBTDevices();
        }
        if I use the above code, the qdialog scandialog does open when the process begins and closes when the data is loaded in qlistwidget, but the contents of qdialog scandialog are not displayed. If I were to change show() to exec(), the contents will be shown but the QProcess does not run until the dialog is closed.

        I want the dialog to open when the Qprocess starts and close when the qlistwidget is loaded with data from the scan. And I want the contents of scandialog to be displayed. It has two labels. One with .GIF file and another with text saying scanning.

        Any help is appreciated.

        Answer - 1
        0 arrow_circle_up 0 arrow_circle_down
        The problem is that QDialog::exec and QProcess::waitForFinished functions block event loop. Never ever block event loop. So you just need to do things more asynchronously.

        QProcess class can be handled asynchronously using signals like readReadStandardOutput. And QDialog can be shown asynchronously using open slot.

        The example:

        void ScanBTDevices() {
        // Open dialog when process is started
        connect(process, SIGNAL(started()), dialog, SLOT(open()));

        // Read standard output asynchronously
        connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyRead()));
        
        // Start process asynchronously (for example I use recursive ls)
        process->start("ls -R /");
        

        }

        void onReadyRead() {
        // Write to list widget
        dialog->appendText(QString(process->readAllStandardOutput()));
        }
        The data will be appended to the dialog during generating by process. Also using QProcess::finished signal and you can close the dialog.

        by *
        Answer - 2 verified
        0 arrow_circle_up 0 arrow_circle_down
        you never return to the event loop when you do show (because of waitForFinished) and you never continue to the processing code when you do exec

        instead of the waitForFinished you should connect to the finished signal and handle it there and use a single shot timer that will cancel it:

        void BTConnect::on_BTscanFinished()//new slot
        {
        //Clear the list widget
        this->ui->listWidget->clear();

        //Read the command line output and store it in QString out
        QString out(BTscan_Process.readAllStandardOutput());
        

        After doing all of this I basically stuck on virtual onboarding software.
        //Split the QString every new line and save theve in a QStringList
        QStringList OutSplit = out.split("\n");

        //Parse the QStringList in btCellsParser
        btCellsParser cp(OutSplit);
        
        for(unsigned int i = 0; i<cp.count(); i++)
        {
           //writing in listwidget
        }
        ScanDialogClose();
        

        }

        void BTConnect::ScanBTDevices()
        {
        ScanDialogShow();

        //Command to scan nearby bluetooth devices
        //"hcitool scan"
        QString cmd("hcitool scan");
        
        //start the process
        connect(BTscan_Process, SIGNAL(finished()), this, SLOT(on_BTscanFinished()));
        BTscan_Process.start(cmd);
        QTimer::singleShot(20000, scan, SLOT(close()));
        

        }

        Hope this will properly help you.

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

        @Jamieghosal Many thanks for the post. I am glad I found somebody who does "Bluetooth" coding.
        Your post is a big help, however at this time I have to fix "updating" QT.
        The example function is OK , but it still keep QT from updating until it is finished. I need to work on that first.

        Speaking of Bluetooth - I am very often experiencing a total "screw-up" - even using commands running terminal won't work. The only "solution" is to switch / reboot to another OS _ I am, running multi-boot - all Ubuntu.

        I really believe "bluez" is the worst application and it is "part of the Linux kernel" - hence I am trying to bypass it using HCI directly.

        1 Reply Last reply
        0
        • C ChrisW67

          The blocking behaviour of hcitool is not a Qt problem. hcitool has options for controlling timeouts (at least the Bluez source code I am looking at does). However, you seem to be running something on Windows, so I have no idea what your hcittool really is.

          Is there a reason that you are not using the Qt Bluetooth support?

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

          @ChrisW67 Yes, QTBluetooth "support" won't even recognize that I turned Bluetooth off in OS - and happily reports "finished " - no error.
          I did try at lest two versions of QTCreator with same result.
          FYI _ I am using Ubuntu.

          1 Reply Last reply
          0
          • JamieghosalJ Jamieghosal

            I am also facing some kind of erroneous things which I am sharing along with btconnect.h file -
            This is my btconnect.h file

            #ifndef BTCONNECT_H
            #define BTCONNECT_H

            #include "scandialog.h"

            namespace Ui {
            class BTConnect;
            }

            class BTConnect : public QWidget
            {
            Q_OBJECT

            public:
            explicit BTConnect(QWidget *parent = 0);
            ~BTConnect();

            private slots:
            void on_ScanButton_clicked();

            void ScanBTDevices();
            
            //some slots here
            
            void ScanDialogShow();
            
            void ScanDialogClose();
            

            public slots:
            //some slots here

            private:
            Ui::BTConnect *ui;

            QProcess BTscan_Process;
            
            scanDialog *scan;
            

            };

            #endif // BTCONNECT_H
            btconnect.cpp

            BTConnect::BTConnect(QWidget *parent) :
            QWidget(parent),
            ui(new Ui::BTConnect)
            {
            //set the userinterface as BTConnect.ui
            ui->setupUi(this);

            scan = new scanDialog(this);
            

            }

            void BTConnect::ScanDialogShow()
            {
            scan->show();
            }

            void BTConnect::ScanDialogClose()
            {
            scan->close();
            }

            void BTConnect::ScanBTDevices()
            {
            ScanDialogShow();

            //Command to scan nearby bluetooth devices
            //"hcitool scan"
            QString cmd("hcitool scan");
            
            //start the process
            BTscan_Process.start(cmd);
            
            //Wait for the processs to finish with a timeout of 20 seconds
            if(BTscan_Process.waitForFinished(20000))
            {
                //Clear the list widget
                this->ui->listWidget->clear();
            
                //Read the command line output and store it in QString out
                QString out(BTscan_Process.readAllStandardOutput());
            
                //Split the QString every new line and save theve in a QStringList
                QStringList OutSplit = out.split("\n");
            
                //Parse the QStringList in btCellsParser
                btCellsParser cp(OutSplit);
            
                for(unsigned int i = 0; i<cp.count(); i++)
                {
                   //writing in listwidget
                }
            
            }
            
            ScanDialogClose();
            

            }

            void BTConnect::on_ScanButton_clicked()
            {
            //Scan for available nearby bluetooth devices
            ScanBTDevices();
            }
            if I use the above code, the qdialog scandialog does open when the process begins and closes when the data is loaded in qlistwidget, but the contents of qdialog scandialog are not displayed. If I were to change show() to exec(), the contents will be shown but the QProcess does not run until the dialog is closed.

            I want the dialog to open when the Qprocess starts and close when the qlistwidget is loaded with data from the scan. And I want the contents of scandialog to be displayed. It has two labels. One with .GIF file and another with text saying scanning.

            Any help is appreciated.

            Answer - 1
            0 arrow_circle_up 0 arrow_circle_down
            The problem is that QDialog::exec and QProcess::waitForFinished functions block event loop. Never ever block event loop. So you just need to do things more asynchronously.

            QProcess class can be handled asynchronously using signals like readReadStandardOutput. And QDialog can be shown asynchronously using open slot.

            The example:

            void ScanBTDevices() {
            // Open dialog when process is started
            connect(process, SIGNAL(started()), dialog, SLOT(open()));

            // Read standard output asynchronously
            connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyRead()));
            
            // Start process asynchronously (for example I use recursive ls)
            process->start("ls -R /");
            

            }

            void onReadyRead() {
            // Write to list widget
            dialog->appendText(QString(process->readAllStandardOutput()));
            }
            The data will be appended to the dialog during generating by process. Also using QProcess::finished signal and you can close the dialog.

            by *
            Answer - 2 verified
            0 arrow_circle_up 0 arrow_circle_down
            you never return to the event loop when you do show (because of waitForFinished) and you never continue to the processing code when you do exec

            instead of the waitForFinished you should connect to the finished signal and handle it there and use a single shot timer that will cancel it:

            void BTConnect::on_BTscanFinished()//new slot
            {
            //Clear the list widget
            this->ui->listWidget->clear();

            //Read the command line output and store it in QString out
            QString out(BTscan_Process.readAllStandardOutput());
            

            After doing all of this I basically stuck on virtual onboarding software.
            //Split the QString every new line and save theve in a QStringList
            QStringList OutSplit = out.split("\n");

            //Parse the QStringList in btCellsParser
            btCellsParser cp(OutSplit);
            
            for(unsigned int i = 0; i<cp.count(); i++)
            {
               //writing in listwidget
            }
            ScanDialogClose();
            

            }

            void BTConnect::ScanBTDevices()
            {
            ScanDialogShow();

            //Command to scan nearby bluetooth devices
            //"hcitool scan"
            QString cmd("hcitool scan");
            
            //start the process
            connect(BTscan_Process, SIGNAL(finished()), this, SLOT(on_BTscanFinished()));
            BTscan_Process.start(cmd);
            QTimer::singleShot(20000, scan, SLOT(close()));
            

            }

            Hope this will properly help you.

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

            @Jamieghosal I think the basic "problem" is

            OProcess.waitForFinished(60000);

            I do not get how QT executes basic C function by "waiting" for it to return "true".
            That basically blocks the rest of the code and I expect "process" not to do that.
            So it back to finding out how to make "process" NOT to block the rest of the code. Long time ago I used QProgressBar and it is the time to try it again - I should be able to "update" the QProgressBar on each second - hence the QProcess needs to be convinced to do so.

            SGaistS 1 Reply Last reply
            0
            • A Anonymous_Banned275

              @Jamieghosal I think the basic "problem" is

              OProcess.waitForFinished(60000);

              I do not get how QT executes basic C function by "waiting" for it to return "true".
              That basically blocks the rest of the code and I expect "process" not to do that.
              So it back to finding out how to make "process" NOT to block the rest of the code. Long time ago I used QProgressBar and it is the time to try it again - I should be able to "update" the QProgressBar on each second - hence the QProcess needs to be convinced to do so.

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #17

              @AnneRanch QProcess is asynchronous as already explained. Learn how to use it that way.

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

              A 1 Reply Last reply
              2
              • SGaistS SGaist

                @AnneRanch QProcess is asynchronous as already explained. Learn how to use it that way.

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

                @SGaist And what do you think I am doing ? I do not need such comments.
                Cheers

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #19

                  Well, you are using the blocking API, hence my suggestion. Stop doing that and use signals and slots to manage your QProcess object.

                  Make a list of the commands you want to execute. Pick the first, start it, then when it is done (use the finished signal to know), start the next on the list and so on until they are all done. No freeze will happen.

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

                  A 1 Reply Last reply
                  3
                  • SGaistS SGaist

                    Well, you are using the blocking API, hence my suggestion. Stop doing that and use signals and slots to manage your QProcess object.

                    Make a list of the commands you want to execute. Pick the first, start it, then when it is done (use the finished signal to know), start the next on the list and so on until they are all done. No freeze will happen.

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

                    @SGaist Tep, that is what I am doing and as usual I am stuck on "connect".
                    Sure could use a real example of connect to get me going...
                    This "wait for completion" sure was of no help to really understand QProcess...

                    J.HilkJ 1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #21

                      There's an example in the finished signal documentation using a lambda.
                      There's a chapter dedicated to the explanation on how signal and slots work.

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

                      1 Reply Last reply
                      1
                      • A Anonymous_Banned275

                        @SGaist Tep, that is what I am doing and as usual I am stuck on "connect".
                        Sure could use a real example of connect to get me going...
                        This "wait for completion" sure was of no help to really understand QProcess...

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #22

                        @AnneRanch said in text append waits until hcitoo scan is finished:

                        Tep, that is what I am doing and as usual I am stuck on "connect".
                        Sure could use a real example of connect to get me going...
                        This "wait for completion" sure was of no help to really understand QProcess...

                        does this help?

                        #ifndef HCITOOLPROCESS_H
                        #define HCITOOLPROCESS_H
                        
                        #include <QObject>
                        #include <QProcess>
                        #include <QElapsedTimer>
                        #include <iostream>
                        
                        class HciToolProcess : public QObject
                        {
                            Q_OBJECT
                        public:
                            enum HciCommands : uint8_t {
                                Dev,
                                Inq,
                                Scan,
                            };
                        
                            explicit HciToolProcess(QObject *parent = nullptr) : QObject(parent), m_currentCommand{HciCommands::Dev}
                            {
                                connect(&m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &HciToolProcess::nextCommand);
                            }
                        
                            bool startProcess(){
                                if(m_currentCommand != HciCommands::Dev)
                                    return false;
                        
                                m_elapsedTime.start();
                        
                                m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite);
                        
                                return true;
                            }
                        
                        signals:
                            void timeElapsed(const QString &time); // to update your textEdit_2
                            void allProcessesDone();
                        
                        private:
                            void nextCommand(int exitCode, QProcess::ExitStatus exitStatus){
                                std::cout<<"\n * Program to demonstrate the usage of linux commands in qt * \n";
                        
                                QString StdOut      =   m_process.readAllStandardOutput();  //Reads standard output
                                QString StdError    =   m_process.readAllStandardError();   //Reads standard error
                        
                                std::cout<<"\n Printing the standard output..........\n";
                                std::cout<<std::endl<<StdOut.toStdString();
                                std::cout<<"\n Printing the standard error..........\n";
                                std::cout<<std::endl<<StdError.toStdString();
                                std::cout<<"\n Printing exit code..........\n";
                                std::cout<<std::endl<<exitCode;
                                std::cout<<"\n Printing exitStatus..........\n";
                                std::cout<<std::endl<<exitStatus;
                                std::cout<<"\n\n";
                        
                                QString elapsedTime = QString::number(m_elapsedTime.restart());
                                emit timeElapsed(elapsedTime);
                        
                                m_currentCommand = static_cast<HciCommands>(m_currentCommand + 1);
                                if(static_cast<uint8_t>(m_currentCommand) <= static_cast<uint8_t>(HciCommands::Scan)){
                                    m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite);
                                } else {
                                    m_currentCommand = HciCommands::Dev;
                                    emit allProcessesDone();
                                }
                            }
                        
                            QString HciCommandToString( HciCommands cmd) {
                                switch (cmd) {
                                case HciCommands::Dev: return QStringLiteral("dev");
                                case HciCommands::Inq: return QStringLiteral("inq");
                                case HciCommands::Scan: return QStringLiteral("scan");
                                default:
                                    Q_UNREACHABLE();
                                    return QLatin1String();
                                }
                            }
                        
                        private:
                            QElapsedTimer m_elapsedTime;
                            HciCommands m_currentCommand;
                            QProcess m_process;
                        };
                        
                        #endif // HCITOOLPROCESS_H
                        
                        

                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        JonBJ 1 Reply Last reply
                        2
                        • J.HilkJ J.Hilk

                          @AnneRanch said in text append waits until hcitoo scan is finished:

                          Tep, that is what I am doing and as usual I am stuck on "connect".
                          Sure could use a real example of connect to get me going...
                          This "wait for completion" sure was of no help to really understand QProcess...

                          does this help?

                          #ifndef HCITOOLPROCESS_H
                          #define HCITOOLPROCESS_H
                          
                          #include <QObject>
                          #include <QProcess>
                          #include <QElapsedTimer>
                          #include <iostream>
                          
                          class HciToolProcess : public QObject
                          {
                              Q_OBJECT
                          public:
                              enum HciCommands : uint8_t {
                                  Dev,
                                  Inq,
                                  Scan,
                              };
                          
                              explicit HciToolProcess(QObject *parent = nullptr) : QObject(parent), m_currentCommand{HciCommands::Dev}
                              {
                                  connect(&m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &HciToolProcess::nextCommand);
                              }
                          
                              bool startProcess(){
                                  if(m_currentCommand != HciCommands::Dev)
                                      return false;
                          
                                  m_elapsedTime.start();
                          
                                  m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite);
                          
                                  return true;
                              }
                          
                          signals:
                              void timeElapsed(const QString &time); // to update your textEdit_2
                              void allProcessesDone();
                          
                          private:
                              void nextCommand(int exitCode, QProcess::ExitStatus exitStatus){
                                  std::cout<<"\n * Program to demonstrate the usage of linux commands in qt * \n";
                          
                                  QString StdOut      =   m_process.readAllStandardOutput();  //Reads standard output
                                  QString StdError    =   m_process.readAllStandardError();   //Reads standard error
                          
                                  std::cout<<"\n Printing the standard output..........\n";
                                  std::cout<<std::endl<<StdOut.toStdString();
                                  std::cout<<"\n Printing the standard error..........\n";
                                  std::cout<<std::endl<<StdError.toStdString();
                                  std::cout<<"\n Printing exit code..........\n";
                                  std::cout<<std::endl<<exitCode;
                                  std::cout<<"\n Printing exitStatus..........\n";
                                  std::cout<<std::endl<<exitStatus;
                                  std::cout<<"\n\n";
                          
                                  QString elapsedTime = QString::number(m_elapsedTime.restart());
                                  emit timeElapsed(elapsedTime);
                          
                                  m_currentCommand = static_cast<HciCommands>(m_currentCommand + 1);
                                  if(static_cast<uint8_t>(m_currentCommand) <= static_cast<uint8_t>(HciCommands::Scan)){
                                      m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite);
                                  } else {
                                      m_currentCommand = HciCommands::Dev;
                                      emit allProcessesDone();
                                  }
                              }
                          
                              QString HciCommandToString( HciCommands cmd) {
                                  switch (cmd) {
                                  case HciCommands::Dev: return QStringLiteral("dev");
                                  case HciCommands::Inq: return QStringLiteral("inq");
                                  case HciCommands::Scan: return QStringLiteral("scan");
                                  default:
                                      Q_UNREACHABLE();
                                      return QLatin1String();
                                  }
                              }
                          
                          private:
                              QElapsedTimer m_elapsedTime;
                              HciCommands m_currentCommand;
                              QProcess m_process;
                          };
                          
                          #endif // HCITOOLPROCESS_H
                          
                          
                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by
                          #23

                          @J-Hilk
                          I was thinking about writing something like this, but assumed the effort would be ignored.

                          If you were to get rid of your enumeration/switch statement and instead create some list of the commands (plus parameters) to be used, which the caller passes/sets on the class, it would be a generic "execute any arbitrary list of commands sequentially" class.

                          J.HilkJ 1 Reply Last reply
                          0
                          • JonBJ JonB

                            @J-Hilk
                            I was thinking about writing something like this, but assumed the effort would be ignored.

                            If you were to get rid of your enumeration/switch statement and instead create some list of the commands (plus parameters) to be used, which the caller passes/sets on the class, it would be a generic "execute any arbitrary list of commands sequentially" class.

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by J.Hilk
                            #24

                            @JonB sure, here ya go :D

                            #ifndef HCITOOLPROCESS_H
                            #define HCITOOLPROCESS_H
                            
                            #include <QObject>
                            #include <QProcess>
                            #include <QElapsedTimer>
                            #include <iostream>
                            
                            class HciToolProcess : public QObject
                            {
                                Q_OBJECT
                            public:
                            
                                struct CommandAndArguments{
                                    QString command;
                                    QStringList arguments;
                                };
                            
                                explicit HciToolProcess(QObject *parent = nullptr) : QObject(parent), m_index{-1}
                                {
                                    connect(&m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &HciToolProcess::onProcessFinished);
                                }
                            
                                bool startProcess(QList<CommandAndArguments> commands){
                                    if(m_index != -1 || commands.isEmpty())
                                        return false;
                            
                                    m_cmdAndArgs = commands;
                            
                                    m_elapsedTime.start();
                            
                                    //m_index is -1 so the function will set it to 0
                                    processCommandAndArguments();
                            
                                    return true;
                                }
                            
                            signals:
                                void timeElapsed(const QString &time); // to update your textEdit_2
                                void allProcessesDone();
                            
                            private:
                                void processCommandAndArguments(){
                                    m_index++;
                                    if(m_index < m_cmdAndArgs.size()){
                                        m_process.start(m_cmdAndArgs.at(m_index).command, m_cmdAndArgs.at(m_index).arguments, QIODevice::ReadWrite);
                                    } else {
                                        m_index = -1;
                                        emit allProcessesDone();
                                    }
                                }
                            
                                void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus){
                                    std::cout<<"\n * Program to demonstrate the usage of linux commands in qt * \n";
                            
                                    QString StdOut      =   m_process.readAllStandardOutput();  //Reads standard output
                                    QString StdError    =   m_process.readAllStandardError();   //Reads standard error
                            
                                    std::cout<<"\n Printing the standard output..........\n";
                                    std::cout<<std::endl<<StdOut.toStdString();
                                    std::cout<<"\n Printing the standard error..........\n";
                                    std::cout<<std::endl<<StdError.toStdString();
                                    std::cout<<"\n Printing exit code..........\n";
                                    std::cout<<std::endl<<exitCode;
                                    std::cout<<"\n Printing exitStatus..........\n";
                                    std::cout<<std::endl<<exitStatus;
                                    std::cout<<"\n\n";
                            
                                    QString elapsedTime = QString::number(m_elapsedTime.restart());
                                    emit timeElapsed(elapsedTime);
                            
                                    processCommandAndArguments();
                                }
                            
                            private:
                                QElapsedTimer m_elapsedTime;
                                QProcess m_process;
                                QList<CommandAndArguments> m_cmdAndArgs;
                                int32_t m_index;
                            };
                            
                            #endif // HCITOOLPROCESS_H
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            1 Reply Last reply
                            3

                            • Login

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