QML 앱에서 시스템 명령 실행


16

내 응용 프로그램 내부에서 시스템 명령을 실행하고 싶습니다. SSH를 사용하여 원격 서버에서 명령을 실행한다고 가정합니다. 그러나 그것은 실제로 요점이 아닙니다. 요점은 앱에서 어떤 종류의 명령을 실행하는 방법을 모른다는 것입니다. 메일리스트에서 물었고 C ++을 사용하여 QML 확장을 빌드하라고했습니다. 그러나 C ++을 모르고 간단한 명령을 실행하기 위해 많은 것을 배워야하는 것 같습니다.

Python에서 (PHP 에서처럼) 시스템 명령을 실행하는 것이 쉽습니다. Touch 앱에 다른 방법이 있습니까? 아니면 더 도움이 될만한 사람이 있습니까? 아니면 내 문제에 대한 더 나은 해결책이 있습니까?


1
"마인 크래프트 서버", "재미있는 재미"를 배우는 방법 등 질문의 핵심과 관련이없는 모든 내용을 제거 할 수 있습니까? 내가 묻는 이유는 이러한 세부 사항이 문제 옆에 있고 정중하게 산만하기 때문입니다.
Akiva

답변:


13

이것은 QML이 지원하는 것이 아니며 일반적인 대답은 C ++ 플러그인을 작성하여 그러한 종류의 것을 처리하는 것입니다.

그러나 SDK 팀은 QML 앱 개발자에게 제공 할 다양한 확장 프로그램을 계획하고 있으며 이는 사용자가 사용할 수있는 일반 플러그인으로 구현 한 것일 수 있습니다.


2
대단히 감사하겠습니다! 대신 Python 스크립트를 호출하는 방법을 찾기 시작했지만 QML을 실행하는 Python 스크립트 만 찾을 수 있습니다.
Daniel Holm

마지막으로 새 앱과 동일한 기능을 위해 webui를 일부 변경하고 XML을 사용하여 필요한 정보를 가져 왔습니다. 꽤 깔끔한.
Daniel Holm

1
14.04에서 QProcess Launcher 개념을 사용해 보았으며 제대로 작동합니다. askubuntu.com/a/446736/20275
int_ua

@ mhall119 내가 틀렸다면 저를 정정하십시오. 그러나 AppArmor 때문에 실제로 전화로 QML을 사용 하여이 작업을 수행 할 수는 없습니다. 이렇게하지 못하게됩니다.
Akiva

10

업데이트 : 14.04의 경우 int_ua의 단순화 된 답변을 참조하십시오.

원문 :

에서 http://talk.maemo.org/showthread.php?t=87580 QML에 확장자를 추가하는 방법에 대한 기본 개요가있다. 대신 우분투 SDK를 사용하여 촬영하기로 결정했습니다. 이는 약간 다릅니다. 아래에 문서화하겠습니다.

이 프로젝트를 위해 내가 선택한 QtCreator에서 C ++ 백엔드가 있는 Ubuntu Touch / Simple UI를 했습니다. QML로 작성된 백엔드와 touchui 프론트 엔드의 두 부분으로 구성된 프로젝트가 생성됩니다. 백엔드에 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 "launcher.h"

과에 BackendPlugin :: registerTypes이 줄을 추가 :

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

포함 된 예제 인 MyType에 대한 행이 이미 있어야합니다. 이 후 우리는 백엔드를 구축 할 수 있어야합니다. 남아있는 유일한 것은 main.qml 파일에서 사용하는 것입니다. 이를 위해 줄을 추가했습니다.

Launcher { id: myLauncher }

Button의 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이 작동합니다.


지금은 단지 14.04에서 작동하는 것 : askubuntu.com/a/446736/20275을
int_ua

6

우분투 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");

다음 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
이 솔루션이 저에게 매우 효과적이라는 것을 확인하고 싶습니다. 어떤 명령을 입력하든 출력은 사각형으로 표시됩니다.
Akiva

2

터미널 명령에 액세스하기 위해 c ++에 대해 많이 알 필요가 없습니다. runPython.cpp와 같이 .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.