Uruchom polecenia systemowe z aplikacji QML


16

Chcę uruchomić polecenie systemowe z poziomu mojej aplikacji. Przypuszczalnie uruchom polecenie na zdalnym serwerze za pomocą SSH. Ale tak naprawdę nie o to chodzi. Chodzi o to, że nie wiem, jak uruchomić dowolne polecenie z aplikacji. Zapytałem na liście mailowej, a oni polecili mi zbudowanie rozszerzenia QML przy użyciu C ++. Ale nie znam C ++ i wydaje się, że muszę się wiele nauczyć, aby uruchomić proste polecenie.

W Pythonie (jak w PHP) łatwo jest uruchomić polecenie systemowe. Czy jest jakiś inny sposób, aby to zrobić w mojej aplikacji Touch, czy jest ktoś, kto mógłby mi jeszcze bardziej pomóc? A może masz lepsze rozwiązanie mojego problemu?


1
Czy możesz usunąć wszystkie treści niezwiązane z rdzeniem pytania, takie jak „Serwer Minecraft”, Jak uczysz się tego „Dla zabawy” itp.? Powodem, dla którego pytam, jest to, że te szczegóły są obok problemu i dość rozpraszają, z szacunkiem.
Akiva

Odpowiedzi:


13

Nie jest to obsługiwane przez QML, typową odpowiedzią jest napisanie wtyczki C ++ do obsługi tego rodzaju rzeczy.

Jednak zespół SDK planuje różne rozszerzenia, które mają zapewnić programistom aplikacji QML, i może to być coś, co implementują w ogólnej wtyczce, której można użyć.


2
Byłoby to bardzo mile widziane! Zamiast tego zacząłem szukać sposobu na wywołanie skryptu w języku Python, ale mogę znaleźć tylko skrypt w języku Python, który uruchamia QML, a nie na odwrót.
Daniel Holm

W końcu zrobiłem to, że wprowadziłem pewne zmiany w moim webui dla tej samej funkcji co nowa aplikacja i wyciągnąłem potrzebne informacje z tego przy użyciu XML. Całkiem nieźle.
Daniel Holm

1
Próbowałem programu uruchamiającego QProcess w 14.04 i działa dobrze: askubuntu.com/a/446736/20275
int_ua

@ mhall119 Proszę mnie poprawić, jeśli się mylę, ale tak naprawdę nie można tego zrobić za pomocą QML na telefonie z powodu AppArmor. Uniemożliwi to ci to zrobić.
Akiva

10

Aktualizacja: 14.04 zobacz znacznie uproszczoną odpowiedź int_ua.

Oryginalny tekst:

Na stronie http://talk.maemo.org/showthread.php?t=87580 znajduje się podstawowy przegląd dodawania rozszerzenia do QML. Postanowiłem spróbować zamiast tego za pomocą ubuntu-sdk, co jest nieco inne. Udokumentuję poniżej.

Do tego projektu wybrałem Ubuntu Touch / Simple UI z C ++ Backend w QtCreator. Tworzy to projekt z dwiema oddzielnymi częściami: backendem i frontonem touchui napisanym w QML. Do backendu dodamy dwa pliki dla klasy 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;
}

Ta klasa po prostu używa QProcess do wykonania programu, czeka na zakończenie, odczytuje standardowe wyjście i zwraca jako ciąg znaków.

Następnie musimy zmodyfikować backend / backend.cpp, aby uwzględnić klasę. Wymaga to dwóch linii. Dołącz dołącz:

#include "launcher.h"

i w BackendPlugin :: registerTypes dodaj linię:

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

Powinien już być wiersz dla MyType, który jest dołączonym przykładem. Po tym powinniśmy być w stanie zbudować backend. Pozostaje tylko użyć go w pliku main.qml. W tym celu dodałem wiersz:

Launcher { id: myLauncher }

i w module obsługi onClick przycisku ustaw:

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

W tym momencie pozostaje tylko uruchomienie i przetestowanie. Tutaj natknąłem się na problem, ponieważ QtCreator nie wydaje się domyślnie konfigurować wszystkiego poprawnie. W miarę obejścia tego problemu w terminalu przejdź do katalogu projektu QtCreator i:

mkdir -p Ubuntu/Example

Następnie skopiuj plik libUbuntuExample.so z ProjectBuildDir / backend do Ubuntu / Example, a plik qmldir z ProjectName / backend / qmldir. Następnie możesz uruchomić:

qmlscene -I . ProjectName/touchui/main.qml

Jestem pewien, że istnieje prawdopodobnie prosty sposób, aby wszystko to spreparować, więc Build / Run po prostu działa.


Teraz działa tylko w 14.04: askubuntu.com/a/446736/20275
int_ua

6

Ubuntu 14.04

Koncepcja typu QProcess Launcher działa teraz bez problemów w Trusty z ubuntu-sdk-teamPPA. Po prostu utwórz QML Extension Library + Tabbed UIprojekt ( nie używaj jeszcze łączników w nazwie projektu ), zamień zawartość

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

}

i zmiany qmlRegisterTypew backend.cppDo

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

Następnie po prostu wyczyść wszystkie MyTypepozostałości z plików QML i dodaj

        Rectangle {

          Launcher {
             id: qprocess
          }

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

gdziekolwiek chcesz i

import projectname 1.0

na początku.

Opcjonalny

Używam również tego opakowania:

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

Jeśli potrzebujesz dostępu do konta root, dodaj pkexec.


1
Chciałbym tylko potwierdzić, że to rozwiązanie działało dla mnie doskonale. Bez względu na to, jakie polecenia wprowadzisz, jego wynik jest wyświetlany w prostokącie.
Akiva

2

Naprawdę nie musisz dużo wiedzieć o c ++, aby uzyskać dostęp do poleceń terminala. Po prostu umieść poniższe w dowolnym pliku z rozszerzeniem .cpp, na przykład runPython.cpp.

#include <stdlib.h>

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

Teraz musisz tylko dowiedzieć się, jak uruchomić kod c ++ w QML, ale jestem pewien, że jest to bardzo dobrze udokumentowane.

Zauważ, że możesz dodać dowolne polecenie linux, postępując zgodnie z tą samą składnią system("linux command");.

Mam nadzieję że to pomoże!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.