Запустіть системні команди з програми QML


16

Я хочу запустити системну команду всередині моєї програми. Припустимо, запустити команду на віддаленому сервері за допомогою SSH. Але це насправді не сенс. Справа в тому, що я не знаю, як запускати будь-які команди з програми. Я запитав у списку пошти, і вони направили мене створити розширення QML за допомогою C ++. Але я не знаю C ++, і, здається, мені доводиться вчитися стільки, щоб виконати просту команду.

У Python (як і в PHP) легко запустити системну команду. Чи є якийсь інший спосіб зробити це в моєму додатку Touch, чи є хтось, хто міг би мені ще більше допомогти? Чи, можливо, краще вирішити мою проблему?


1
Чи можете ви видалити весь вміст, не пов’язаний із основою вашого запитання, як-от "Сервер Minecraft", Як ви вивчаєте це "Просто заради задоволення" тощо? Я питаю, тому що ці деталі поруч із проблемою і досить відволікають, з повагою.
Аківа

Відповіді:


13

Це не те, що підтримує QML, типова відповідь - написати плагін C ++ для обробки подібних речей.

Однак команда SDK планує різні розширення для розробки розробників додатків QML, і це може бути те, що вони реалізують у загальному плагіні, який ви можете використовувати.


2
Це було б дуже вдячно! Я замість цього почав шукати спосіб викликати сценарій Python, але я можу знайти лише сценарій Python, який працює з QML, а не навпаки.
Даніель Холм

Що я нарешті зробив, це те, що я змінив свій веб-сайт для тієї ж функції, що і новий додаток, і витягніть потрібну інформацію з цього за допомогою XML. Досить акуратно.
Даніель Холм

1
Я спробував концепцію запуску QProcess в 14.04, і вона працює чудово: askubuntu.com/a/446736/20275
int_ua

@ mhall119 Будь ласка, виправте мене, якщо я помиляюся, але ви не можете зробити це з QML на телефоні через AppArmor. Це заважатиме вам це робити.
Аківа

10

Оновлення: 14.04 див. Значно спрощену відповідь від int_ua.

Оригінальний текст:

На http://talk.maemo.org/showthread.php?t=87580 наведено основний огляд того, як додати розширення до QML. Я вирішив зробити знімок, використовуючи натомість ubuntu-sdk, який трохи відрізняється. Я документую нижче.

Для цього проекту я вибрав Ubuntu Touch / Simple інтерфейс користувача з C ++ Backend у QtCreator. Це створює проект із двох окремих частин, бекенда та сенсорного фронту, написаних у QML. До бекенда ми додамо два файли для класу 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 }

і на обробник onClick Button встановіть:

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 просто працює.


Зараз він працює лише в 14.04: askubuntu.com/a/446736/20275
int_ua

6

Ubuntu 14.04

Концепція типу QProcess Launcher зараз без проблем працює в Trusty з ubuntu-sdk-teamPPA. Просто створіть 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() {

}

і зміни qmlRegisterTypeв backend.cppTo

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.


1
Я просто хотів би підтвердити, що це рішення спрацювало чудово для мене. Які б команди ви не вводили, його вихід відображається у прямокутнику.
Аківа

2

Вам дійсно не потрібно багато знати про c ++, щоб отримати доступ до термінальних команд. Просто введіть наступне у будь-який файл, що закінчується .cpp, наприклад runPython.cpp.

#include <stdlib.h>

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

Все, що вам потрібно зараз з’ясувати, - це як запустити код c ++ у QML, але я впевнений, що це дуже добре задокументовано.

Зауважте, що ви можете додати будь-яку команду linux, яка вам подобається, дотримуючись того самого синтаксису system("linux command");.

Сподіваюся, це допомагає!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.