web-dev-qa-db-ja.com

QMLアプリからシステムコマンドを実行する

アプリケーション内からシステムコマンドを実行したい。 SSHを使用してリモートサーバーでコマンドを実行することを想定しています。しかし、それは本当にポイントではありません。ポイントは、アプリからどのような種類のコマンドも実行する方法がわからないということです。メールリストで尋ねると、C++を使用してQML拡張機能を構築するように言われました。しかし、私はC++を知らず、単純なコマンドを実行するためだけに多くを学ばなければならないようです。

Python(PHPの場合)では、システムコマンドを簡単に実行できます。 Touchアプリで他の方法でそれを行う方法はありますか?それとも私の問題に対するより良い解決策がありますか?

16
Daniel Holm

これはQMLがサポートするものではありません。典型的な答えは、そのようなことを処理するC++プラグインを作成することです。

ただし、SDKチームはQMLアプリ開発者に提供するさまざまな拡張機能を計画しています。これは、使用可能な汎用プラグインで実装するものです。

13
mhall119

更新:14.04については、int_uaによる非常に簡略化された回答を参照してください。

元のテキスト:

http://talk.maemo.org/showthread.php?t=8758 に、QMLに拡張機能を追加する方法の基本的な概要があります。代わりにubuntu-sdkを使用してショットを作成することにしましたが、これは少し異なります。以下に文書化します。

このプロジェクトでは、QtCreatorでC++バックエンドを使用したUbuntuタッチ/シンプルUIを選択しました。これにより、QMLで記述されたバックエンドとtouchuiフロントエンドの2つの別個の部分を持つプロジェクトが作成されます。バックエンドに、Launcherクラスの2つのファイルを追加します。

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を変更してクラスを含める必要があります。これには2行が必要です。インクルードを追加します。

#include "launcher.h"

そしてBackendPlugin :: registerTypesで行を追加します:

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

含まれる例であるMyTypeの行が既にあるはずです。この後、バックエンドを構築できるはずです。残っているのは、main.qmlファイルで使用することだけです。このために、次の行を追加しました。

Launcher { id: myLauncher }

そして、ボタンの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

おそらく、これをすべてリグする簡単な方法があるので、ビルド/実行が機能するはずです。

10
Jason Conti

Ubuntu 14.04

QProcess Launcherタイプの概念は、ubuntu-sdk-team PPAを使用したTrustyで問題なく機能するようになりました。 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() {

}

backend.cppqmlRegisterTypeを変更します

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

次に、すべてのMyTypeをQMLファイルから削除して追加します

        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 \"")
}

ルートアクセスが必要な場合は、pkexecを追加します。

6
int_ua

端末コマンドにアクセスするために、c ++について多くを知る必要はありません。 runPython.cppのように、.cppで終わる任意のファイルに次の行を追加するだけです。

#include <stdlib.h>

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

あなたが今見つけなければならないのは、QMLでc ++コードを実行する方法だけですが、それは非常によく文書化されていると確信しています。

同じ構文system("linux command");に従うことで、好きなLinuxコマンドを追加できることに注意してください。

お役に立てれば!

2
user93692