How to run a shell script from qml ?



  • I'm running Qt Creator 2.8.1 based on Qt 5.1.1 x64 and I'm trying to run a shell script ( just a basic test script ) from qml file. Somehow, this doesn't work for me and I'm not sure where the error is ?! Any help would be appreciated.

    My files:

    main.qml

    @import QtQuick 2.0

    Rectangle {
    width: 360
    height: 360

    Text {
        text: "Hello World"
        anchors.centerIn: parent
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: ScriptLauncher.launchScript("bash")
    
    }
    

    }
    @

    main.cpp

    @#include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include "scriptlauncher.h"
    #include <QQmlContext>
    #include <QQmlComponent>

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/scriptest2/main.qml"&#41;&#41;;
    viewer.showExpanded(&#41;;
    
    ScriptLauncher  launcher;
    
    QQmlContext *context =viewer.rootContext();
    context->setContextProperty("ScriptLauncher", &launcher);
    
    //qmlRegisterType[removed]("myScriptLauncher", 1, 0, "ScriptLauncher");
    
    
    return app.exec&#40;&#41;;
    

    }
    @

    scriptlauncher.cpp

    @#include "scriptlauncher.h"

    ScriptLauncher::ScriptLauncher(QObject *parent) :
    QObject(parent),
    m_process(new QProcess(this))
    {

    }

    void ScriptLauncher::launchScript()
    {
    m_process->start("./test.sh");

    }
    @

    ScriptLauncher.h

    @#ifndef SCRIPTLAUNCHER_H
    #define SCRIPTLAUNCHER_H

    #include <QObject>
    #include <QProcess>

    class ScriptLauncher : public QObject
    {

    Q_OBJECT
    

    public:
    explicit ScriptLauncher(QObject *parent = 0);
    Q_INVOKABLE void launchScript();

    private:
    QProcess *m_process;
    };

    #endif // SCRIPTLAUNCHER_H
    @



  • Hello there are you sure that you do not need to run your script in a emulator like gnome-terminal or something like that ?

    I also notice in your qml file that you are calling the launcherscript() but you are giving it parameters

    @
    MouseArea {
    anchors.fill: parent
    onClicked: ScriptLauncher.launchScript("bash")
    }@

    But there is no parameters in your c++ code. You are just calling a script. Maybe try to make it
    @

    MouseArea {
    anchors.fill: parent
    onClicked: ScriptLauncher.launchScript()

    }@
    

    Unless you want to make it so you can pass application names and scripts to QProcess

    example

    @
    void ScriptLauncher::launchScript(const QString &App)
    {
    m_process->start(App); // call a property that is passed from QML

    }
    @

    and make that the same in you header file

    @
    Q_INVOKABLE void launchScript(const QString &App);
    @

    You could also make these properties available to QML with the Q_PROPERTY tag in you header files. Too Learn more about that check out the docs on C++ qml integration or Here is a full Qml Plugin if you would like to look at it.
    https://github.com/bobweaver/qml-applauncher

    Here is a example
    @
    import QtQuick 2.0
    import ApplicationLauncher 1.0
    Rectangle {
    width: 360
    height: 360

    Text {
        text: "Hello World"
        anchors.centerIn: parent
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            launcher.launchScript()
        }
    }
    Application{
        id: launcher
    

    // or some path to a script run in a bash emulator like gnome-terminal or something like that.
    appName: "vlc"
    }

    @



  • Tnx for your suggestion. I've seen the mistake in this example. It is a leftover after many different test attemps. My MouseArea is actually empty. I have tried every posible combination and many other things., but still, somehow, it doesn't work ( ScriptLauncher.launchScript() ).

    I want to run just a simple script to confirm that it works - and then i would implement something you have suggested in your example. But I can't get a confirmation.

    I've build a tutorial project from /example/extend and it works, but it use QtQuick 1.0.

    In any case, thanks your suggestion and help. It is appreciated.



  • Here is a Example of How you can do this. But I suggest reading more on qprocess and what you can do with it.

    application.cpp
    @
    #include "application.h"
    #include <QProcess>
    #include <QDebug>
    Application::Application(QObject *parent) :
    QObject(parent),
    m_process(new QProcess(this))
    {
    }
    QString Application::appName() const
    {
    return m_AppName;
    }
    void Application::setAppName(const QString &appName)
    {
    m_AppName = appName;
    }
    void Application::launchScript()
    {
    // You can use start() if you want to start a external application
    m_process->execute(m_AppName);
    }
    @

    application.h

    @
    #ifndef APPLICATION_H
    #define APPLICATION_H
    #include <QObject>
    #include <QProcess>
    class Application : public QObject
    {
    Q_OBJECT

    public:
    explicit Application(QObject *parent = 0);

    Q_PROPERTY( QString appName READ appName WRITE setAppName )
    
    QString appName() const;
    void setAppName(const QString &appName);
    
    Q_INVOKABLE void launchScript();
    

    private:
    QProcess *m_process;
    QString m_AppName;
    };
    #endif //APPLICATION_H
    @

    main.cpp
    @
    #include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include <qqml.h>
    #include "application.h"
    int main(int argc, char *argv[])
    {

    QGuiApplication app(argc, argv);
    qmlRegisterType<Application>("Application", 1 , 0 , "App");
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/untitled9/main.qml"&#41;&#41;;
    viewer.showExpanded();
    return app.exec&#40;&#41;;
    

    }
    @

    main.qml
    @
    import QtQuick 2.0
    import Application 1.0
    Rectangle {
    width: 360
    height: 360
    Text {
    text: qsTr("Hello World")
    anchors.centerIn: parent
    }
    App{
    id: bar
    appName:"echo "Hello" This is a Simple test from C++"
    }
    MouseArea {
    anchors.fill: parent
    onClicked: {
    bar.launchScript()
    }
    }
    }
    @



  • Excelent !

    This worked perfectly.... I will take your advice and I will look deeper into the qprocess docs. Thank you for your help and a great example....


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.