QT中C++程序和QML的集成

QT的C++和QML框架中,後端的C++程序,對於前端的QML程序來說,它實際上是QML程序的服務器,在QT的官方推薦文檔中,採用瞭如下方法來實現C++程序的註冊:

qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd");

其中:

  • io.qt.examples.backend 是QML文件中需要引用的QML的包名;
  • 1 是大版本號;
  • 0 是小版本號;
  • BackEnd 是C++生成的QML對象,以使在QML文件中,對C++生成的QML對象進行操作;
    同時在QML文件中需要引入
import io.qt.examples.backend 1.0

詳見 QML和C++的集成官方文檔

但這種方法,總感覺有點彆扭,主要是因爲:

  1. C++作爲後臺的服務器,幹嘛要註冊成爲一個QML的組件?
  2. C++註冊的QML組件,如果在多個QML中使用,會不會實現了多個實例化,也就是說出現了多個服務器,如果是並行處理也就算了,如果是單一服務器,如何保證它們之間的數據同步
  3. 如果在C++的程序裏面,定義了對象,對象中又定義了對象;那麼在QML中如要對底層對象的屬性和方法進行調用,豈不是特別麻煩?

實際上,QT還有另外一種方式,來註冊C++的程序:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QIcon>
#include <QQuickStyle>
#include <QQmlContext>

#include "corecalculate.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    // 本地存儲設置
    app.setOrganizationName("weisuansuan");
    app.setOrganizationDomain("weisuansuan.top");
    app.setApplicationName("WeiSuanSuan Application");

    // 設置icon
    QIcon::setThemeName("weisuansuan");

    // 設置樣式
    QQuickStyle::setStyle("Material");

    // 設置後臺程序
    QQmlContext *ctx = engine.rootContext();
    CoreCalculate core;

    ctx->setContextProperty("myCore", &core);
    ctx->setContextProperty("myLoan", &core.loan);
    ctx->setContextProperty("myModel", &core.mylistModel);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

這裏在C++程序中,首先引入頭文件:

#include <QQmlContext>

獲取QMLContext對象

    QQmlContext *ctx = engine.rootContext();

實例化C++對象

CoreCalculate core;

對C++對象的不同部分,進行分別註冊

    ctx->setContextProperty("myCore", &core);
    ctx->setContextProperty("myLoan", &core.loan);
    ctx->setContextProperty("myModel", &core.mylistModel);

在QML文件中,不需要引入文件,直接可以對

  • myCore
  • myLoan
  • myModel

進行操作;在QML中,它們是獨立的,沒有任何關係,後臺的C++對象core,保證了它們的數據同步。

參見課程 《QT QML跨平臺移動APP編程》 有詳細的解答

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章