Запустить системные команды из приложения QML

16

Я хочу запустить системную команду из моего приложения. Предполагается запустить команду на удаленном сервере с помощью SSH. Но это не совсем так. Дело в том, что я не знаю, как запускать какую-либо команду из приложения. Я спросил в списке писем, и они сослались на создание расширения QML с использованием C ++. Но я не знаю C ++, и кажется, что мне нужно многому научиться только для запуска простой команды.

В Python (как и в PHP) легко запустить системную команду. Есть ли другой способ сделать это в приложении Touch, или есть кто-то, кто может мне помочь еще больше? Или, возможно, лучшее решение моей проблемы?

    
задан Daniel Holm 30.04.2013 в 15:18
источник

4 ответа

13

Это не то, что поддерживает QML, типичный ответ - написать плагин C ++ для обработки такого рода вещей.

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

    
ответ дан mhall119 30.04.2013 в 16:35
источник
10

Обновление: для 14.04 см. упрощенный ответ by int_ua.

Исходный текст:

В Ссылка приведен общий обзор того, как добавить расширение в QML. Я решил сделать снимок, используя вместо этого ubuntu-sdk, который немного отличается. Я опишу ниже.

Для этого проекта я выбрал Ubuntu Touch / Simple UI с C ++ Backend в QtCreator. Это создает проект с двумя отдельными частями, бэкэнд и интерфейсом touchui, написанными в QML. Для бэкэнда мы собираемся добавить два файла для класса 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:

#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 просто работает.

    
ответ дан Jason Conti 29.06.2013 в 01:05
6

Ubuntu 14.04

Концепция QProcess Launcher теперь работает без проблем в Trusty с ubuntu-sdk-team PPA. Просто создайте QML Extension Library + Tabbed UI project ( не используйте дефисы в имени проекта еще ), замените содержимое

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.cpp на

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

Если вам нужен root-доступ, добавьте pkexec .

    
ответ дан int_ua 12.04.2014 в 06:30
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"); .

Надеюсь, это поможет!

    
ответ дан user93692 16.08.2013 в 00:53