Jalankan perintah sistem dari Aplikasi QML

16

Saya ingin menjalankan perintah sistem dari dalam aplikasi saya. Seharusnya menjalankan perintah pada server jauh menggunakan SSH. Tapi bukan itu intinya. Intinya adalah saya tidak tahu cara menjalankan perintah apa pun dari aplikasi. Saya bertanya dalam daftar surat dan mereka merujuk saya untuk membangun ekstensi QML menggunakan C ++. Tapi saya tidak tahu C ++ dan sepertinya saya harus belajar banyak hanya untuk menjalankan perintah sederhana.

Dalam Python (seperti dalam PHP) mudah untuk menjalankan perintah sistem. Apakah ada cara lain untuk melakukannya di aplikasi Touch saya, atau adakah orang yang bisa membantu saya lebih banyak? Atau mungkin punya solusi yang lebih baik untuk masalah saya?

Daniel Holm
sumber
1
Bisakah Anda menghapus semua konten yang tidak ada hubungannya dengan inti pertanyaan Anda, seperti "Server Minecraft", Bagaimana Anda mempelajari ini "Hanya untuk bersenang-senang", dll? Alasan saya bertanya adalah karena rincian ini di samping masalah dan cukup mengganggu, dengan hormat.
Akiva

Jawaban:

13

Ini bukan sesuatu yang didukung QML, jawabannya adalah menulis plugin C ++ untuk menangani hal semacam itu.

Namun, tim SDK merencanakan berbagai ekstensi untuk diberikan kepada pengembang aplikasi QML, dan ini mungkin sesuatu yang mereka terapkan dalam plugin generik yang dapat Anda gunakan.

mhall119
sumber
2
Itu akan sangat dihargai! Alih-alih, saya mulai mencari cara untuk memanggil skrip Python, tetapi saya hanya dapat menemukan skrip Python yang menjalankan QML, dan bukan sebaliknya.
Daniel Holm
Apa yang akhirnya saya lakukan adalah saya membuat beberapa perubahan pada webui saya untuk fungsi yang sama dengan aplikasi baru, dan menarik info yang saya perlukan dari itu menggunakan XML. Cukup rapi.
Daniel Holm
1
Saya sudah mencoba konsep Peluncur QProcess pada 14,04 dan berfungsi dengan baik: askubuntu.com/a/446736/20275
int_ua
@ mhall119 Harap perbaiki saya jika saya salah, tetapi Anda sebenarnya tidak dapat melakukan ini dengan QML di telepon karena AppArmor. Ini akan mencegah Anda melakukan hal ini.
Akiva
10

Pembaruan: Untuk 14,04 lihat jawaban yang paling disederhanakan oleh int_ua.

Teks asli:

Di http://talk.maemo.org/showthread.php?t=87580 ada ikhtisar dasar tentang cara menambahkan ekstensi ke QML. Saya memutuskan untuk mencobanya menggunakan ubuntu-sdk sebagai gantinya, yang sedikit berbeda. Saya akan mendokumentasikan di bawah ini.

Untuk proyek ini saya memilih Ubuntu Touch / Simple UI dengan C ++ Backend di QtCreator. Ini menciptakan sebuah proyek dengan dua bagian terpisah, backend dan touchui frontend yang ditulis dalam QML. Untuk backend kita akan menambahkan dua file untuk kelas 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;
}

Kelas ini hanya menggunakan QProcess untuk menjalankan suatu program, menunggu sampai selesai, membaca stdout-nya, dan mengembalikannya sebagai string.

Selanjutnya kita perlu memodifikasi backend / backend.cpp untuk memasukkan kelas. Ini membutuhkan dua baris. Tambahkan sebuah termasuk:

#include "launcher.h"

dan di BackendPlugin :: registerTypes tambahkan baris:

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

Seharusnya sudah ada baris untuk MyType, yang merupakan contoh yang disertakan. Setelah ini, kita harus dapat membangun backend. Satu-satunya yang tersisa adalah menggunakannya di file main.qml. Untuk ini saya menambahkan baris:

Launcher { id: myLauncher }

dan ke handler onClick Button, atur:

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

Pada titik ini yang tersisa hanyalah memulai dan mengujinya. Di sinilah saya mengalami masalah, karena QtCreator tampaknya tidak mengatur semuanya dengan benar secara default. Saat saya mengatasinya, di terminal navigasikan ke direktori proyek QtCreator Anda dan:

mkdir -p Ubuntu/Example

Kemudian salin file libUbuntuExample.so dari ProjectBuildDir / backend ke Ubuntu / Contoh, dan file qmldir dari ProjectName / backend / qmldir. Maka Anda dapat menjalankan:

qmlscene -I . ProjectName/touchui/main.qml

Saya yakin mungkin ada cara sederhana untuk mengatur semua ini sehingga Build / Run berfungsi.

Jason Conti
sumber
Sekarang hanya berfungsi di 14.04: askubuntu.com/a/446736/20275
int_ua
6

Ubuntu 14.04

Konsep tipe Peluncur QProcess sekarang bekerja tanpa masalah di Trusty dengan ubuntu-sdk-teamPPA. Buat saja QML Extension Library + Tabbed UIproyek ( jangan gunakan tanda hubung dalam nama proyek ), ganti konten

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

}

dan perubahan qmlRegisterTypedalam backend.cppuntuk

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

Selanjutnya, cukup bersihkan semua MyTypesisa dari file QML dan tambahkan

        Rectangle {

          Launcher {
             id: qprocess
          }

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

dimanapun Anda suka dan

import projectname 1.0

pada awalnya.

Pilihan

Saya juga menggunakan pembungkus ini:

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

Jika Anda membutuhkan akses root, tambahkan pkexec.

int_ua
sumber
1
Saya hanya ingin mengkonfirmasi bahwa solusi ini bekerja sangat baik untuk saya. Apapun perintah yang Anda input, outputnya ditampilkan dalam kotak.
Akiva
2

Anda benar-benar tidak perlu tahu banyak tentang c ++ untuk mendapatkan akses ke perintah terminal. Masukkan saja yang berikut ini di file yang diakhiri dengan .cpp, misalnya runPython.cpp.

#include <stdlib.h>

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

Yang harus Anda ketahui sekarang adalah bagaimana agar kode c ++ berjalan di QML tapi saya yakin itu didokumentasikan dengan sangat baik.

Perhatikan bahwa Anda dapat menambahkan perintah linux yang Anda suka dengan mengikuti sintaks yang sama system("linux command");.

Semoga ini membantu!

pengguna93692
sumber