QML Uygulaması'ndan sistem komutlarını çalıştırma


16

Uygulamamın içinden bir sistem komutu çalıştırmak istiyorum. SSH kullanarak uzak bir sunucuda komut çalıştırması gerekiyor. Ama asıl mesele bu değil. Mesele şu ki, uygulamadan herhangi bir komutu nasıl çalıştıracağımı bilmiyorum. Posta listesinde sordum ve C ++ kullanarak bir QML uzantısı oluşturmak için beni sevk etti. Ama C ++ bilmiyorum ve sadece basit bir komut çalıştırmak için çok şey öğrenmek zorunda gibi görünüyor.

Python'da (PHP'de olduğu gibi) bir sistem komutu çalıştırmak kolaydır. Touch uygulamamda yapmanın başka bir yolu var mı, yoksa bana daha fazla yardımcı olabilecek biri var mı? Ya da belki de sorunum için daha iyi bir çözüm var mı?


1
Sorunuzun çekirdeği ile ilgili olmayan, "Minecraft Server", "Nasıl eğlenmek için" nasıl öğreniyorsunuz? Gibi tüm içeriği kaldırabilir misiniz? Sormamın nedeni, bu ayrıntıların sorunun yanında olması ve saygıyla dikkat dağıtıcı olmasıdır.
Akiva

Yanıtlar:


13

Bu QML'nin desteklediği bir şey değil, tipik cevap bu tür şeyleri işlemek için bir C ++ eklentisi yazmaktır.

Bununla birlikte, SDK ekibi QML uygulama geliştiricilerine sağlamak için çeşitli uzantılar planlamaktadır ve bu, kullanabileceğiniz genel bir eklentide uyguladıkları bir şey olabilir.


2
Bu çok takdir edilecektir! Bunun yerine bir Python betiği çağırmak için bir yol aramaya başladım, ama sadece QML çalıştıran bir Python betiği bulabilirim, tersi değil.
Daniel Holm

Sonunda yaptığım şey, yeni uygulamayla aynı işlev için webui'mde bazı değişiklikler yapmam ve XML kullanarak ihtiyaç duyduğum bilgileri çekmemdi. Oldukça temiz.
Daniel Holm

1
QProcess Launcher konseptini 14.04'te denedim ve gayet iyi çalışıyor: askubuntu.com/a/446736/20275
int_ua

@ mhall119 Yanılıyorsam lütfen beni düzeltin, ancak bunu AppArmor nedeniyle telefonda QML ile yapamazsınız. Bunu yapmanı engelleyecektir.
Akiva

10

Güncelleme: 14.04 için int_ua'nın çok basitleştirilmiş cevabına bakınız.

Orjinal metin:

Http://talk.maemo.org/showthread.php?t=87580 adresinde , uzantıyı QML'ye nasıl ekleyeceğinize ilişkin temel bir genel bakış vardır. Bunun yerine ubuntu-sdk'yi kullanarak denemeye karar verdim, ki bu biraz farklı. Aşağıda belgeleyeceğim.

Bu proje için QtCreator'da C ++ Arka Uçlu Ubuntu Touch / Simple UI'yi seçtim. Bu, QML'de yazılmış arka uç ve touchui ön ucu olmak üzere iki ayrı bölüm içeren bir proje oluşturur. Arka uca, Launcher sınıfı için iki dosya ekleyeceğiz.

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;
}

Bu sınıf, bir programı yürütmek için QProcess'i kullanır, bitmesini bekler, stdout'unu okur ve bir dize olarak döndürür.

Daha sonra sınıfı dahil etmek için backend / backend.cpp dosyasını değiştirmeniz gerekiyor. Bu iki satır gerektirir. Dahil et:

#include "launcher.h"

ve BackendPlugin :: registerTypes'de bir satır ekleyin:

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

Dahil edilen örnek olan MyType için zaten bir satır olmalıdır. Bundan sonra arka ucu oluşturabilmeliyiz. Geriye kalan tek şey main.qml dosyasında kullanmaktır. Bunun için bir satır ekledim:

Launcher { id: myLauncher }

ve Button öğesinin onClick işleyicisine şunları ayarlayın:

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

Bu noktada geriye kalan tek şey onu başlatmak ve test etmektir. QtCreator varsayılan olarak her şeyi düzgün ayarlanmış gibi görünmediği için burada bir sorunla karşılaştım. Geçici çözüm olarak, terminalde QtCreator proje dizininize gidin ve:

mkdir -p Ubuntu/Example

Ardından libUbuntuExample.so dosyasını ProjectBuildDir / arka uçtan Ubuntu / Örnek'e ve qmldir dosyasını ProjectName / backend / qmldir'den kopyalayın. Sonra çalıştırabilirsiniz:

qmlscene -I . ProjectName/touchui/main.qml

Eminim tüm bunları donatmak için basit bir yol var, bu yüzden Build / Run sadece çalışır.


Şimdi sadece 14.04'te
int_ua

6

Ubuntu 14.04

QProcess Launcher türü kavramı şimdi ubuntu-sdk-teamPPA ile Trusty'de sorunsuz çalışıyor . Sadece QML Extension Library + Tabbed UIproje oluşturun ( henüz proje adında kısa çizgiler kullanmayın ), içeriğini değiştirin

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

}

ve değişim qmlRegisterTypeiçinde backend.cppTo

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

Ardından, MyTypeQML dosyalarındaki tüm kalıntıları temizleyin ve ekleyin

        Rectangle {

          Launcher {
             id: qprocess
          }

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

nerede istersen ve

import projectname 1.0

başlangıçta.

İsteğe bağlı

Ben de bu sarıcı kullanın:

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

Kök erişimine ihtiyacınız varsa ekleyin pkexec.


1
Bu çözümün benim için mükemmel bir şekilde çalıştığını doğrulamak istiyorum. Girdiğiniz komutlar ne olursa olsun, çıktısı dikdörtgende görüntülenir.
Akiva

2

Terminal komutlarına erişmek için gerçekten c ++ hakkında çok şey bilmenize gerek yok. Aşağıdakileri .cpp ile biten herhangi bir dosyaya koyun, örneğin runPython.cpp.

#include <stdlib.h>

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

Şimdi tüm öğrenmek zorunda nasıl QML çalışan c ++ kodu almaktır ama eminim bu çok iyi belgelenmiş.

Aynı sözdizimini izleyerek istediğiniz linux komutunu ekleyebileceğinizi unutmayın system("linux command");.

Bu yardımcı olur umarım!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.