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.6k 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 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 Online
        jsulmJ Online
        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