从QML App运行系统命令


16

我想从我的应用程序内部运行系统命令。假设使用SSH在远程服务器上运行命令。但这不是重点。关键是我不知道如何从应用程序运行任何类型的命令。我在邮件列表中询问,他们推荐我使用C ++构建QML扩展。但是我不了解C ++,看来我只需要运行一个简单的命令就学到很多东西。

在Python(如PHP)中,运行系统命令很容易。我的Touch应用程序中还有其他方法可以使用它吗,或者有人可以为我提供更多帮助?也许有更好的解决方案来解决我的问题?


1
您是否可以删除与问题的核心无关的所有内容,例如“ Minecraft服务器”,如何学习“仅仅是为了好玩”等?我问的原因是因为这些细节不在问题之列,而且很令人分心,请尊重。
Akiva 2014年

Answers:


13

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

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


2
那将不胜感激!相反,我开始寻找一种调用Python脚本的方法,但是我只能找到运行QML的Python脚本,而不能找到另一种方法。
Daniel Holm

最后我要做的是,对Webui进行了一些更改,以使其具有与新应用相同的功能,并使用XML从中获取所需的信息。很简约。
丹尼尔·霍尔姆

1
我已经在14.04中尝试了QProcess Launcher概念,并且效果很好:askubuntu.com/a/446736/20275
int_ua 2014年

@ mhall119如果我错了,请纠正我,但是由于AppArmor,您实际上无法在电话上使用QML进行此操作。这将阻止您执行此操作。
Akiva

10

更新:对于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 <QObject>
#include <QProcess>

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<Launcher>(uri, 1, 0, "Launcher");

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

Launcher { id: myLauncher }

并为Button的onClick处理程序设置:

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

此时,剩下的就是启动它并进行测试。这是我遇到问题的地方,因为QtCreator在默认情况下似乎并未正确设置所有内容。在解决问题时,请在终端中导航至您的QtCreator项目目录,然后:

mkdir -p Ubuntu/Example

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

qmlscene -I . ProjectName/touchui/main.qml

我敢肯定,可能有一种简单的方法可以完成所有工作,因此“构建/运行”就可以了。


现在仅适用于14.04版:askubuntu.com/a/446736/20275
int_ua 2014年

6

Ubuntu 14.04

ubuntu-sdk-teamPPA的Trusty中,QProcess Launcher类型的概念现在可以正常使用了。只需创建QML Extension Library + Tabbed UI项目(尚未在项目名称中使用连字符),替换以下内容

mytype.h

#ifndef LAUNCHER_H
#define LAUNCHER_H

#include <QObject>
#include <QProcess>

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() {

}

和变革qmlRegisterTypebackend.cpp

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

接下来,只需清除MyTypeQML文件中的所有残留物并添加

        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


1
我只想确认此解决方案对我来说非常有效。无论您输入什么命令,其输出都会显示在矩形中。
Akiva

2

您真的不需要了解c ++就能访问终端命令。只需将以下内容放在任何以.cpp结尾的文件中,例如runPython.cpp。

#include <stdlib.h>

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

现在您需要查找的就是如何使Q ++在QML中运行,但是我敢肯定,它已经被很好地记录了下来。

请注意,您可以按照相同的语法添加所需的任何Linux命令system("linux command");

希望这可以帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.