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
但这种方法,总感觉有点别扭,主要是因为:
- C++作为后台的服务器,干嘛要注册成为一个QML的组件?
- C++注册的QML组件,如果在多个QML中使用,会不会实现了多个实例化,也就是说出现了多个服务器,如果是并行处理也就算了,如果是单一服务器,如何保证它们之间的数据同步
- 如果在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编程》 有详细的解答