从QML App运行系统命令

我想从我的应用程序内部运行系统命令。 假设使用SSH在远程服务器上运行命令。 但这不是重点。 关键是我不知道如何从应用程序运行任何类型的命令。 我在邮件列表中询问,他们让我使用C ++构建QML扩展。 但是我不知道C ++,似乎我必须学习这么多才能运行一个简单的命令。

在Python中(如在PHP中),运行系统命令很容易。 有没有其他方法可以在我的Touch应用程序中执行此操作,或者是否有人可以帮助我更多? 或者对我的问题有更好的解决方案?

这不是QML支持的,典型的答案是编写一个C ++插件来处理这种事情。

但是,SDK团队正计划向QML应用程序开发人员提供各种扩展,这可能是他们在您可以使用的通用插件中实现的。

更新:对于14.04,请参阅int_ua的简化答案。

原文:

在http://talk.maemo.org/showthread.php?t=87580中,有一个如何将扩展添加到QML的基本概述。 我决定用ubuntu-sdk来试一试,这有点不同。 我将在下面记录。

对于这个项目,我在QtCreator中选择了带有C ++后端的Ubuntu Touch / Simple UI 。 这创建了一个包含两个独立部分的项目,后端和用QML编写的touchui前端。 对于后端,我们将为Launcher类添加两个文件。

launcher.h:

#ifndef LAUNCHER_H #define LAUNCHER_H #include  #include  class Launcher : public QObject { Q_OBJECT public: explicit Launcher(QObject *parent = 0); Q_INVOKABLE QString launch(const QString &program); private: QProcess *m_process; }; #endif // LAUNCHER_H 

launcher.cpp:

 #include "launcher.h" Launcher::Launcher(QObject *parent) : QObject(parent), m_process(new QProcess(this)) { } QString Launcher::launch(const QString &program) { m_process->start(program); m_process->waitForFinished(-1); QByteArray bytes = m_process->readAllStandardOutput(); QString output = QString::fromLocal8Bit(bytes); return output; } 

这个类只是使用QProcess来执行一个程序,等待它完成,读取它的stdout,然后将它作为一个字符串返回。

接下来我们需要修改backend / backend.cpp以包含该类。 这需要两行。 附加一个包括:

 #include "launcher.h" 

并在BackendPlugin :: registerTypes中添加一行:

 qmlRegisterType(uri, 1, 0, "Launcher"); 

MyType应该已经有一行,这是包含的示例。 在此之后我们应该能够构建后端。 唯一剩下的就是在main.qml文件中使用它。 为此,我添加了一行:

 Launcher { id: myLauncher } 

和Button的onClick处理程序,设置:

 myType.helloWorld = myLauncher.launch("date"); 

在这一点上,剩下的就是启动并测试它。 这是我遇到问题的地方,因为QtCreator默认情况下似乎没有正确设置所有内容。 当我解决方法时,在终端导航到您的QtCreator项目目录并:

 mkdir -p Ubuntu/Example 

然后将libUbuntuExample.so文件从ProjectBuildDir / backend复制到Ubuntu / Example,并将qmldir文件从ProjectName / backend / qmldir复制。 然后你可以运行:

 qmlscene -I . ProjectName/touchui/main.qml 

我确信可能有一种简单的方法来完成这一切,因此Build / Run正常工作。

Ubuntu 14.04

现在,QProcess Launcher类型的概念在使用ubuntu-sdk-team PPA的Trusty中没有问题。 只需创建QML Extension Library + Tabbed UI项目( 不要在项目名称中使用连字符 ),替换内容

mytype.h

 #ifndef LAUNCHER_H #define LAUNCHER_H #include  #include  class Launcher : public QObject { Q_OBJECT public: explicit Launcher(QObject *parent = 0); ~Launcher(); Q_INVOKABLE QString launch(const QString &program); protected: QProcess *m_process; }; #endif // LAUNCHER_H 

mytype.cpp

 #include "mytype.h" Launcher::Launcher(QObject *parent) : QObject(parent), m_process(new QProcess(this)) { } QString Launcher::launch(const QString &program) { m_process->start(program); m_process->waitForFinished(-1); QByteArray bytes = m_process->readAllStandardOutput(); QString output = QString::fromLocal8Bit(bytes); return output; } Launcher::~Launcher() { } 

并将backend.cpp中的qmlRegisterType更改为

 qmlRegisterType(uri, 1, 0, "Launcher"); 

接下来,只需从QML文件中清除所有MyType保留并添加

  Rectangle { Launcher { id: qprocess } Text { anchors.centerIn: parent text: qprocess.launch("which bash") } } 

无论你喜欢什么地方

 import projectname 1.0 

在一开始的时候。

可选的

我也使用这个包装器:

 function exec(command) { return qprocess.launch("sh -c \"" + command + " < /dev/null \"") } 

如果您需要root访问权限,请添加pkexec

你真的不需要了解很多关于c ++来访问终端命令的知识。 只需将以下内容放在以.cpp结尾的任何文件中,例如runPython.cpp。

 #include  int main () { system("cd /home/user/path/to/script"); system("python3 myScript.py"); return 0; } 

现在你需要知道的是如何在QML中运行c ++代码,但我确信这些代码已经有了很好的记录。

请注意,您可以按照相同的语法system("linux command");添加任何您喜欢的system("linux command");

希望这可以帮助!