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: 360Text { 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(QStringLiteral("qml/scriptest2/main.qml")); viewer.showExpanded(); ScriptLauncher launcher; QQmlContext *context =viewer.rootContext(); context->setContextProperty("ScriptLauncher", &launcher); //qmlRegisterType[removed]("myScriptLauncher", 1, 0, "ScriptLauncher"); return app.exec();
}
@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-applauncherHere is a example
@
import QtQuick 2.0
import ApplicationLauncher 1.0
Rectangle {
width: 360
height: 360Text { 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_OBJECTpublic:
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(QStringLiteral("qml/untitled9/main.qml")); viewer.showExpanded(); return app.exec();
}
@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()
}
}
}
@ -
Mind that the call is asynchronous. Hence the command sends a signal when it finishes, and a different part of the code picks the signal and continues with the next step you want to perform.