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


16

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

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


1
「Minecraftサーバー」、この「楽しみのために」をどのように学んでいるかなど、質問の核心に関係しないすべてのコンテンツを削除できますか?私が尋ねる理由は、これらの詳細が問題の横にあり、かなり気を散らすからです。
アキバ14

回答:


13

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

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


2
それは大歓迎です!代わりに、Pythonスクリプトを呼び出す方法を探し始めましたが、QMLを実行するPythonスクリプトしか見つけることができず、他の方法を見つけることはできません。
ダニエルホルム

最後にしたことは、新しいアプリと同じ機能のためにwebuiにいくつかの変更を加え、XMLを使用して必要な情報を引き出したことです。きれいです。
ダニエルホルム

1
私は14.04でQProcessランチャーのコンセプトを試みたし、それが正常に動作します:askubuntu.com/a/446736/20275を
int_ua

@ mhall119私が間違っている場合は修正してください。ただし、AppArmorのために電話でQMLを使用して実際にこれを行うことはできません。これを行うことができなくなります。
アキバ

10

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

元のテキスト:

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

このプロジェクトでは、QtCreatorでUbuntu Touch / Simple UI with C ++ Backendを選択しました。これにより、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

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


14.04で機能するようになりました:askubuntu.com/a/446736/20275
int_ua

6

Ubuntu 14.04

QProcess Launcherタイプの概念は、ubuntu-sdk-teamPPAを使用した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() {

}

そして、変化する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 \"")
}

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


1
この解決策が私にとって非常にうまくいったことを確認したいと思います。どのコマンドを入力しても、その出力は長方形で表示されます。
アキバ

2

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

#include <stdlib.h>

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

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

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

お役に立てれば!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.