Chạy các lệnh hệ thống từ Ứng dụng QML


16

Tôi muốn chạy một lệnh hệ thống từ bên trong ứng dụng của mình. Giả sử chạy lệnh trên máy chủ từ xa bằng SSH. Nhưng đó không thực sự là vấn đề. Vấn đề là tôi không biết cách chạy bất kỳ loại lệnh nào từ ứng dụng. Tôi đã hỏi trong danh sách thư và họ giới thiệu tôi xây dựng tiện ích mở rộng QML bằng C ++. Nhưng tôi không biết C ++ và dường như tôi phải học rất nhiều chỉ để chạy một lệnh đơn giản.

Trong Python (như trong PHP), thật dễ dàng để chạy một lệnh hệ thống. Có cách nào khác để làm điều đó trong ứng dụng Touch của tôi không, hoặc có ai đó có thể giúp tôi nhiều hơn không? Hoặc có lẽ có một giải pháp tốt hơn cho vấn đề của tôi?


1
Bạn có thể xóa tất cả nội dung không liên quan đến cốt lõi câu hỏi của bạn, chẳng hạn như "Máy chủ Minecraft", Làm thế nào bạn học được điều này "Chỉ để giải trí", v.v.? Lý do tôi hỏi là vì những chi tiết này bên cạnh vấn đề và khá mất tập trung, tôn trọng.
Akiva

Câu trả lời:


13

Đây không phải là thứ mà QML hỗ trợ, câu trả lời điển hình là viết một plugin C ++ để xử lý loại đó.

Tuy nhiên, nhóm SDK đang lên kế hoạch cho nhiều tiện ích mở rộng khác nhau để cung cấp cho các nhà phát triển ứng dụng QML và đây có thể là thứ họ triển khai trong một plugin chung mà bạn có thể sử dụng.


2
Điều đó sẽ được nhiều đánh giá cao! Thay vào đó, tôi đã bắt đầu tìm cách gọi một tập lệnh Python, nhưng tôi chỉ có thể tìm thấy một tập lệnh Python chạy QML chứ không phải là cách khác.
Daniel Holm

Điều cuối cùng tôi đã làm là tôi đã thực hiện một số thay đổi cho webui của mình cho cùng chức năng với ứng dụng mới và lấy thông tin tôi cần từ đó bằng cách sử dụng XML. Khá gọn gàng.
Daniel Holm

1
Tôi đã thử khái niệm Trình khởi chạy QProcess vào ngày 14.04 và nó hoạt động tốt: Askubfox.com/a/446736/20275
int_ua

@ mhall119 Vui lòng sửa cho tôi nếu tôi sai, nhưng bạn thực sự không thể làm điều này với QML trên điện thoại vì AppArmor. Nó sẽ ngăn bạn làm điều này.
Akiva

10

Cập nhật: Cho 14.04 xem câu trả lời đơn giản hơn nhiều bởi int_ua.

Văn bản gốc:

Tại http://talk.maemo.org/showthread.php?t=87580 có một tổng quan cơ bản về cách thêm tiện ích mở rộng vào QML. Tôi đã quyết định cho nó một shot bằng cách sử dụng ubfox-sdk, điều này hơi khác một chút. Tôi sẽ tài liệu dưới đây.

Đối với dự án này, tôi đã chọn Ubuntu Touch / Simple UI với C ++ Backend trong QtCreator. Điều này tạo ra một dự án với hai phần riêng biệt, phần phụ trợ và phần đầu vào touchui được viết bằng QML. Đến phần cuối, chúng ta sẽ thêm hai tệp cho lớp 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;
}

Lớp này chỉ đơn giản là sử dụng QProcess để thực thi một chương trình, đợi cho nó kết thúc, đọc thiết bị xuất chuẩn của nó và trả về nó dưới dạng một chuỗi.

Tiếp theo, chúng ta cần sửa đổi backend / backend.cpp để bao gồm lớp. Điều này đòi hỏi hai dòng. Nối một bao gồm:

#include "launcher.h"

và trong BackendPlugin :: registerTypes thêm một dòng:

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

Nên có một dòng cho MyType, đây là ví dụ đi kèm. Sau này, chúng ta sẽ có thể xây dựng phần phụ trợ. Điều duy nhất còn lại là sử dụng nó trong tệp main.qml. Đối với điều này, tôi đã thêm một dòng:

Launcher { id: myLauncher }

và đến trình xử lý onClick của Nút, đặt:

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

Tại thời điểm này, tất cả những gì còn lại là khởi động nó và kiểm tra nó. Đây là nơi tôi gặp phải một vấn đề, vì QtCreator dường như không thiết lập mọi thứ theo đúng mặc định. Khi tôi giải quyết, trong thiết bị đầu cuối điều hướng đến thư mục dự án QtCreator của bạn và:

mkdir -p Ubuntu/Example

Sau đó sao chép tệp libUbfoxExample.so từ ProjectBuildDir / backend sang Ubuntu / Ví dụ và tệp qmldir từ ProjectName / backend / qmldir. Sau đó, bạn có thể chạy:

qmlscene -I . ProjectName/touchui/main.qml

Tôi chắc chắn có một cách đơn giản để khắc phục tất cả những điều này để Build / Run chỉ hoạt động.


Bây giờ nó chỉ hoạt động vào 14.04: Askubfox.com/a/446736/20275
int_ua

6

Ubuntu 14.04

Khái niệm về loại Trình khởi chạy QProcess hiện đang hoạt động mà không gặp sự cố trong Trusty với ubuntu-sdk-teamPPA. Chỉ cần tạo QML Extension Library + Tabbed UIdự án ( chưa sử dụng dấu gạch nối trong tên dự án ), thay thế nội dung của

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

}

và sự thay đổi qmlRegisterTypetrong backend.cppđể

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

Tiếp theo, chỉ cần làm sạch tất cả các MyTypephần còn lại từ các tệp QML và thêm

        Rectangle {

          Launcher {
             id: qprocess
          }

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

bất cứ nơi nào bạn thích và

import projectname 1.0

ở thời điểm bắt đầu.

Không bắt buộc

Tôi cũng sử dụng trình bao bọc này:

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

Nếu bạn cần quyền truy cập root, thêm pkexec.


1
Tôi chỉ muốn xác nhận rằng giải pháp này đã làm việc xuất sắc cho tôi. Bất cứ lệnh nào bạn nhập, đầu ra của nó được hiển thị trong hình chữ nhật.
Akiva

2

Bạn thực sự không cần biết nhiều về c ++ để có quyền truy cập vào các lệnh đầu cuối. Chỉ cần đặt phần sau vào bất kỳ tệp nào kết thúc bằng .cpp, ví dụ runPython.cpp.

#include <stdlib.h>

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

Tất cả những gì bạn phải tìm hiểu bây giờ là làm thế nào để mã c ++ chạy trong QML nhưng tôi chắc chắn rằng đó là tài liệu rất tốt.

Lưu ý rằng bạn có thể thêm bất kỳ lệnh linux nào bạn thích bằng cách làm theo cùng một cú pháp system("linux command");.

Hi vọng điêu nay co ich!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.