Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. run a sh shell while clicking button in QML with QT5.15.0
Forum Updated to NodeBB v4.3 + New Features

run a sh shell while clicking button in QML with QT5.15.0

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
22 Posts 7 Posters 6.7k Views 4 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.
  • L Offline
    L Offline
    lxy12345
    wrote on last edited by
    #3

    Hi, I just want to run an external process which is just a binary file. I write a shell script to run that binary file and want to run this shell while clicking the button in QML.
    Do you have any demo codes?

    mrjjM 1 Reply Last reply
    0
    • L lxy12345

      Hi, I just want to run an external process which is just a binary file. I write a shell script to run that binary file and want to run this shell while clicking the button in QML.
      Do you have any demo codes?

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #4

      @lxy12345
      Hi
      did you try
      http://71.254.128.33/qml/process.html

      L 1 Reply Last reply
      3
      • mrjjM mrjj

        @lxy12345
        Hi
        did you try
        http://71.254.128.33/qml/process.html

        L Offline
        L Offline
        lxy12345
        wrote on last edited by
        #5

        @mrjj Hi, I followed your post but an error occured.
        I copied the process.h file.
        Here below is my main.cpp:
        #include <QGuiApplication>
        #include <QQuickView>
        #include <QQmlEngine>
        #include <QtQml>
        #include "process.h"

        int main(int argc, char* argv[])
        {
        QGuiApplication app(argc,argv);
        QQuickView view;
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        // Qt.quit() called in embedded .qml by default only emits
        // quit() signal, so do this (optionally use Qt.exit()).
        QObject::connect(view.engine(), &QQmlEngine::quit,
        qApp, &QGuiApplication::quit);
        qmlRegisterType<Process>("Process",1,0,"Process");

        view.setSource(QUrl("qrc:///main.qml"));
        //view.resize(1000, 480);
        view.show();
        return app.exec();
        

        }

        Here below is my qml file:
        Item {
        id: usbcam2
        signal clicked
        x:10
        y:450
        width : 140
        height: 70

            BorderImage {
                id: buttonImage2
                source: "images/toolbutton.sci"
                width: usbcam2.width
                height: usbcam2.height
            }
            MouseArea {
                id: mouseRegion2
                anchors.fill: buttonImage2
                onClicked: process.start("/bin/cat", [ "/proc/uptime" ]);
            }
            Text {
                id: btnText2
                anchors.fill: buttonImage2
                anchors.margins: 5
                text: "USBcam2"
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                elide: Text.ElideRight
                color: "white"
                font.bold: true
                style: Text.Raised
                styleColor: "black"
                font.pixelSize: 14
            }
        
        }
        

        }

        When I click the button, the error showed:
        qrc:/main.qml:99: ReferenceError: process is not defined
        what's that meanning?

        ODБOïO 1 Reply Last reply
        0
        • L lxy12345

          @mrjj Hi, I followed your post but an error occured.
          I copied the process.h file.
          Here below is my main.cpp:
          #include <QGuiApplication>
          #include <QQuickView>
          #include <QQmlEngine>
          #include <QtQml>
          #include "process.h"

          int main(int argc, char* argv[])
          {
          QGuiApplication app(argc,argv);
          QQuickView view;
          view.setResizeMode(QQuickView::SizeRootObjectToView);
          // Qt.quit() called in embedded .qml by default only emits
          // quit() signal, so do this (optionally use Qt.exit()).
          QObject::connect(view.engine(), &QQmlEngine::quit,
          qApp, &QGuiApplication::quit);
          qmlRegisterType<Process>("Process",1,0,"Process");

          view.setSource(QUrl("qrc:///main.qml"));
          //view.resize(1000, 480);
          view.show();
          return app.exec();
          

          }

          Here below is my qml file:
          Item {
          id: usbcam2
          signal clicked
          x:10
          y:450
          width : 140
          height: 70

              BorderImage {
                  id: buttonImage2
                  source: "images/toolbutton.sci"
                  width: usbcam2.width
                  height: usbcam2.height
              }
              MouseArea {
                  id: mouseRegion2
                  anchors.fill: buttonImage2
                  onClicked: process.start("/bin/cat", [ "/proc/uptime" ]);
              }
              Text {
                  id: btnText2
                  anchors.fill: buttonImage2
                  anchors.margins: 5
                  text: "USBcam2"
                  horizontalAlignment: Text.AlignHCenter
                  verticalAlignment: Text.AlignVCenter
                  elide: Text.ElideRight
                  color: "white"
                  font.bold: true
                  style: Text.Raised
                  styleColor: "black"
                  font.pixelSize: 14
              }
          
          }
          

          }

          When I click the button, the error showed:
          qrc:/main.qml:99: ReferenceError: process is not defined
          what's that meanning?

          ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by ODБOï
          #6

          @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

          Here below is my qml file:

          you did not create a Process item

           Process {
                  id: process     
              }
          
          L 1 Reply Last reply
          5
          • ODБOïO ODБOï

            @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

            Here below is my qml file:

            you did not create a Process item

             Process {
                    id: process     
                }
            
            L Offline
            L Offline
            lxy12345
            wrote on last edited by
            #7

            @LeLev I don't really understand this code:
            onReadyRead: text.text = readAll();
            Is onReadyRead a signal? or something like onCliked in button?

            jsulmJ 1 Reply Last reply
            0
            • L lxy12345

              @LeLev I don't really understand this code:
              onReadyRead: text.text = readAll();
              Is onReadyRead a signal? or something like onCliked in button?

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #8

              @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

              Is onReadyRead a signal?

              yes

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

              L 1 Reply Last reply
              0
              • jsulmJ jsulm

                @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

                Is onReadyRead a signal?

                yes

                L Offline
                L Offline
                lxy12345
                wrote on last edited by
                #9

                @jsulm Hi, jsulm. I have tried your post but I misunderstand somewhere maybe.
                I don't understand the singal "onReadyRead", I googled which said that this signal is for TCP/IP??? I am not very sure about that.
                what and where should I modify in your post?

                mrjjM 1 Reply Last reply
                0
                • L lxy12345

                  @jsulm Hi, jsulm. I have tried your post but I misunderstand somewhere maybe.
                  I don't understand the singal "onReadyRead", I googled which said that this signal is for TCP/IP??? I am not very sure about that.
                  what and where should I modify in your post?

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

                  onReadyRead

                  Hi
                  Its also for other things.
                  " QProcess emits readyRead() when data is available on the current read channel. It also emits readyReadStandardOutput() when new standard output data is available"

                  https://doc.qt.io/qt-5/qprocess.html
                  in the Communicating via Channels section

                  L 1 Reply Last reply
                  0
                  • mrjjM mrjj

                    @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

                    onReadyRead

                    Hi
                    Its also for other things.
                    " QProcess emits readyRead() when data is available on the current read channel. It also emits readyReadStandardOutput() when new standard output data is available"

                    https://doc.qt.io/qt-5/qprocess.html
                    in the Communicating via Channels section

                    L Offline
                    L Offline
                    lxy12345
                    wrote on last edited by
                    #11

                    @jsulm when I tried the code ,
                    Text {
                    id: text
                    }

                    Process{
                        id: process
                         onReadyRead: text.text = readAll();
                    }
                    Timer {
                         interval: 10
                         repeat: true
                         triggeredOnStart: true
                         running: true
                         onTriggered: process.start("/bin/cat", [ "/proc/uptime" ]);
                     }
                    

                    it outputs:
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running
                    QProcess::start: Process is already running

                    I think that the shell here is just "cat /proc/uptime", it should output some numbers.
                    Maybe I should read and understand Qprocess class first?

                    JonBJ 1 Reply Last reply
                    0
                    • L lxy12345

                      @jsulm when I tried the code ,
                      Text {
                      id: text
                      }

                      Process{
                          id: process
                           onReadyRead: text.text = readAll();
                      }
                      Timer {
                           interval: 10
                           repeat: true
                           triggeredOnStart: true
                           running: true
                           onTriggered: process.start("/bin/cat", [ "/proc/uptime" ]);
                       }
                      

                      it outputs:
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running
                      QProcess::start: Process is already running

                      I think that the shell here is just "cat /proc/uptime", it should output some numbers.
                      Maybe I should read and understand Qprocess class first?

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

                      @lxy12345
                      I don't know anything about QML, but

                      QProcess::start: Process is already running

                      means that you have a QProcess instance where you have set of a start() but it has not yet completed and you have not waited for it, and now you're trying to set off a new start(). You either need to wait for completion of the process instance, or you need to use a new instance of QProcess each time. As I say, i don't know QML how to do that, but that's the cause/reason.

                      1 Reply Last reply
                      2
                      • mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        Hi
                        Since you set the timer to repeat, it will start a new QProcess each time and
                        10 ms might be too short. try raising it so the other Qprocess gets change to finished.

                        Timer {
                        interval: 10
                        repeat: true

                        JonBJ 1 Reply Last reply
                        0
                        • mrjjM mrjj

                          Hi
                          Since you set the timer to repeat, it will start a new QProcess each time and
                          10 ms might be too short. try raising it so the other Qprocess gets change to finished.

                          Timer {
                          interval: 10
                          repeat: true

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

                          @mrjj
                          Really it ought have a handler for "process finished" signal, to be robust. I don't know how you do that from QML.

                          OP might have a go at the naughty:

                               onTriggered: process.start("/bin/cat", [ "/proc/uptime" ]); process.waitForFinished();
                          

                          with all the caveats. I don't know if that would work simpler.

                          mrjjM 1 Reply Last reply
                          1
                          • JonBJ JonB

                            @mrjj
                            Really it ought have a handler for "process finished" signal, to be robust. I don't know how you do that from QML.

                            OP might have a go at the naughty:

                                 onTriggered: process.start("/bin/cat", [ "/proc/uptime" ]); process.waitForFinished();
                            

                            with all the caveats. I don't know if that would work simpler.

                            mrjjM Offline
                            mrjjM Offline
                            mrjj
                            Lifetime Qt Champion
                            wrote on last edited by
                            #15

                            @JonB
                            Yes i agree as guessing on execution time is bound to fail in many other cases.

                            L 1 Reply Last reply
                            0
                            • mrjjM mrjj

                              @JonB
                              Yes i agree as guessing on execution time is bound to fail in many other cases.

                              L Offline
                              L Offline
                              lxy12345
                              wrote on last edited by
                              #16

                              @mrjj finally, I found the reason. I should add console.log() to show output . The post is correct, thanks guys

                              JonBJ 1 Reply Last reply
                              1
                              • L lxy12345

                                @mrjj finally, I found the reason. I should add console.log() to show output . The post is correct, thanks guys

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

                                @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

                                The post is correct

                                What post is correct?

                                L 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @lxy12345 said in run a sh shell while clicking button in QML with QT5.15.0:

                                  The post is correct

                                  What post is correct?

                                  L Offline
                                  L Offline
                                  lxy12345
                                  wrote on last edited by
                                  #18

                                  @JonB http://71.254.128.33/qml/process.html This post.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • L lxy12345

                                    @JonB http://71.254.128.33/qml/process.html This post.

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

                                    @lxy12345
                                    Ah, I see. Yes, that looks reasonable. However, it has no code for waiting for the QProcess::finished signal. I admitted earlier I do not know how QML works with regard to instances. But if it does not create new QProcess instances, and if you re-use the one instance before the cat OS command has completed, you will get the QProcess::start: Process is already running error you showed earlier. Since the /bin/cat /proc/uptime completes "quickly" you may get away with it for a while.

                                    You may well be using this as just an example to play with QProcess, I don't know. But be aware that if you are really trying to do /bin/cat /proc/uptime , that is a waste of time! All that does is an OS command to read the contents of the file. You would be better doing this by just opening the file /proc/uptime and reading its content from QML, without any QProcess OS command at all.

                                    L 1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @lxy12345
                                      Ah, I see. Yes, that looks reasonable. However, it has no code for waiting for the QProcess::finished signal. I admitted earlier I do not know how QML works with regard to instances. But if it does not create new QProcess instances, and if you re-use the one instance before the cat OS command has completed, you will get the QProcess::start: Process is already running error you showed earlier. Since the /bin/cat /proc/uptime completes "quickly" you may get away with it for a while.

                                      You may well be using this as just an example to play with QProcess, I don't know. But be aware that if you are really trying to do /bin/cat /proc/uptime , that is a waste of time! All that does is an OS command to read the contents of the file. You would be better doing this by just opening the file /proc/uptime and reading its content from QML, without any QProcess OS command at all.

                                      L Offline
                                      L Offline
                                      lxy12345
                                      wrote on last edited by
                                      #20

                                      @JonB thanks for replying me. The "cat /proc/uptime" cmd is just an example. I change the cmd in my project, I use this code to open a shell which controls some peripherals.

                                      1 Reply Last reply
                                      0
                                      • foxomanF Offline
                                        foxomanF Offline
                                        foxoman
                                        wrote on last edited by foxoman
                                        #21

                                        Basically close/kill / terminate the process before running a new process
                                        here an example I extracted from one of my projects as I keep "bash" process alive till closing the app itself.
                                        so try to find where you wan to stop the process and close it.

                                        cmd.h

                                        #pragma once
                                        #include <QProcess>
                                        #include <QVariant>
                                        
                                        class Process : public QProcess
                                        {
                                            Q_OBJECT
                                        public:
                                            explicit Process( QObject* parent = Q_NULLPTR ) : QProcess( parent )
                                            { }
                                        
                                             // If want to use Start with arguments
                                            Q_INVOKABLE void start( const QString& program, const QVariantList& arguments )
                                            {
                                                QStringList args;
                                        
                                                // convert QVariantList from QML to QStringList for QProcess
                                                for ( const auto& temp : arguments ) {
                                                    args << temp.toString();
                                                }
                                        
                                                QProcess::setProcessChannelMode( QProcess::MergedChannels );
                                                QProcess::start( program, args );
                                            }
                                        
                                            // If wan to start without arguments for Qt > 5.14
                                            Q_INVOKABLE void start( const QString& program )
                                            {
                                        
                                                QProcess::setProcessChannelMode( QProcess::MergedChannels );
                                                QProcess::setProgram( program );
                                                QProcess::start();
                                                QProcess::open( QProcess::ReadWrite );
                                            }
                                        
                                            Q_INVOKABLE QByteArray readAll() { return QProcess::readAll(); }
                                            Q_INVOKABLE QByteArray readLine() { return QProcess::readLine(); }
                                        
                                             // if you want to write to an active process, not fully tested!
                                            Q_INVOKABLE qint64 write( const QString& data )
                                            {
                                                return QProcess::write( qPrintable( data ) );
                                            }
                                        
                                        private:
                                            Q_DISABLE_COPY( Process )
                                        };
                                        
                                        

                                        In main.h

                                        qmlRegisterType<Process>( "Process", 1, 0, "Process" );
                                        

                                        In main.qml

                                        import QtQuick 2.15
                                        import QtQuick.Controls 2.15
                                        import QtQuick.Layouts 1.15
                                        import Qt.labs.platform 1.1
                                        import Process 1.0
                                        
                                        ApplicationWindow {
                                            visible: true
                                            width: 640
                                            height: 480
                                            title: qsTr("Hello World")
                                        
                                            Component.onCompleted: {
                                                py.start("bash")
                                            }
                                        
                                            // use py.close() or py.kill(0 or py.terminate() to kill the process
                                            Component.onDestruction: py.close()
                                        
                                            Process {
                                                id: py
                                        
                                                property string output: ""
                                        
                                                onStarted: print("Started")
                                                onFinished: print("Closed")
                                        
                                                onErrorOccurred: console.log("Error Ocuured: ", error)
                                        
                                                onReadyReadStandardOutput: {
                                                    output = py.readAll()
                                                    term.text += output
                                                }
                                            }
                                        
                                            Page {
                                        
                                                anchors.fill: parent
                                        
                                                ScrollView {
                                                    id: view
                                                    anchors.fill: parent
                                        
                                                    TextArea {
                                                        id: term
                                                        textFormat: TextArea.RichText
                                                    }
                                                }
                                        
                                                footer: RowLayout {
                                                    Layout.fillWidth: true
                                        
                                                    TextField {
                                                        id: input
                                                        Layout.fillWidth: true
                                                    }
                                                    Button {
                                                        text: "Send!"
                                                        property string command: input.text.trim() + "\n"
                                                        onClicked: {
                                                            py.write(command)
                                                            term.text += ("<br /><b>" + command + " : </b>")
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        
                                        

                                        Test Qml Bash App

                                        I have run cat /proc/uptime as one program command.

                                        Tech Addict, Ubuntu Gnu/Linux Fan and Qt/C++ Developer. || https://www.foxoman.net/

                                        1 Reply Last reply
                                        1
                                        • foxomanF Offline
                                          foxomanF Offline
                                          foxoman
                                          wrote on last edited by
                                          #22

                                          Here is an update to run multiple process as a replay to reddit QA

                                          import QtQuick 2.15
                                          import QtQuick.Controls 2.15
                                          import Process 1.0
                                          
                                          ApplicationWindow {
                                              visible: true
                                              width: 640
                                              height: 480
                                              title: "Run a sh file in CMD!"
                                          
                                              // prcoess to run and read .sh file
                                              Process {
                                                  id: cmd
                                          
                                                  property string output: ""
                                          
                                                  onStarted: print("Started")
                                          
                                                  // Once reading the .sh finish we will run another process to run the notify-send!
                                                  onFinished: notify.start("notify-send",
                                                                           ["-t", "4000", "Reading .sh file Completed!"])
                                          
                                                  onErrorOccurred: console.log("Error Ocuured: ", error)
                                          
                                                  onReadyReadStandardOutput: {
                                                      output = cmd.readAll()
                                                      txt.text += output
                                                  }
                                              }
                                          
                                              // process to run firefox
                                              Process {
                                                  id: fireFox
                                          
                                                  property string output: ""
                                          
                                                  // start notify process once we run firefox!
                                                  onStarted: notify.start("notify-send",
                                                                          ["-t", "4000", "Starting FireFox!"])
                                                  onFinished: print("Closed")
                                          
                                                  onErrorOccurred: console.log("Error Ocuured: ", error)
                                          
                                                  onReadyReadStandardOutput: {
                                                      output = cmd.readAll()
                                                      console.log("READING CONSOLE: ", output)
                                                  }
                                              }
                                          
                                              // process to run notify-osd !!
                                              Process {
                                                  id: notify
                                          
                                                  property string output: ""
                                          
                                                  onStarted: print("Started")
                                                  onFinished: print("Closed")
                                          
                                                  onErrorOccurred: console.log("Error Ocuured: ", error)
                                          
                                                  onReadyReadStandardOutput: {
                                                      output = cmd.readAll()
                                                      console.log("READING CONSOLE: ", output)
                                                  }
                                              }
                                          
                                              Column {
                                                  anchors.centerIn: parent
                                                  TextArea {
                                                      id: txt
                                                      text: ""
                                                  }
                                          
                                                  Row {
                                                      Button {
                                                          text: "Run SH!"
                                                          onClicked: cmd.start("/home/foxoman/file.sh")
                                                      }
                                                      Button {
                                                          text: "Run FireFox!"
                                                          onClicked: fireFox.start("firefox")
                                                      }
                                                      Button {
                                                          text: "Run Notify"
                                                          onClicked: notify.start(
                                                                         "notify-send",
                                                                         ["-t", "4000", "OSD Notify From Command Line!"])
                                                      }
                                                  }
                                              }
                                          }
                                          
                                          
                                          

                                          Tech Addict, Ubuntu Gnu/Linux Fan and Qt/C++ Developer. || https://www.foxoman.net/

                                          1 Reply Last reply
                                          1

                                          • Login

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