从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");
。
希望这可以帮助!