Я хочу запустить системную команду из моего приложения. Предполагается выполнить команду на удаленном сервере, используя SSH. Но дело не в этом. Дело в том, что я не знаю, как запустить какую-либо команду из приложения. Я спросил в списке рассылки, и они направили меня на создание расширения QML с использованием C ++. Но я не знаю C ++, и мне кажется, что мне нужно многому научиться, только чтобы выполнить простую команду.
В Python (как в PHP) легко запустить системную команду. Есть ли другой способ сделать это в моем приложении Touch, или есть кто-то, кто может помочь мне еще больше? Или, может быть, есть лучшее решение моей проблемы?
Это не то, что поддерживает QML, типичный ответ - написать плагин C ++ для обработки таких вещей.
Однако команда SDK планирует различные расширения для предоставления разработчикам приложений QML, и это может быть чем-то, что они реализуют в общем плагине, который вы можете использовать.
Концепция типа QProcess Launcher теперь работает без проблем в Trusty с ubuntu-sdk-team
PPA. Просто создайте проект 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.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
.
Вам действительно не нужно много знать о 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»);
.
Надеюсь, это поможет!
Обновление: для 14.04 см. значительно упрощенный ответ int_ua .
Исходный текст:
На http://talk.maemo.org/showthread.php?t=87580 есть базовый обзор того, как добавить расширение в 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:
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 просто работало.