QML与C++集成<一>——<运行环境以及相关运行时类介绍>
一、概要
Qt提供了Qwidget和QML两种编程方式,这里主要讲解二者组合的编程方式,因为QML引擎与Qt的元对象系统的集成,使得在QML中可以直接调用C++的功能,这种机制还允许QML、JavaScript、C++三者进行混合开发。在QML引擎中集成了Qt元对象系统,所以QObject子类能够将数据或函数提供给QML使用,由QObject派生的所有子类的属性、方法和信号等都可以在QML中访问,QObject的子类将功能暴露给QML的方式如下:
- C++类可以注册未一个可实例化QML类型,这样就可以像其他普通QML对象类型一样在QML代码中被实例化使用;
- C++类可以被注册为一个单例类型,这样就可以在QML代码中导入这个单例对象实例
- C++类的实例可以作为上下文属性或上下文对象嵌入到QML代码中
二、QML运行环境加载
QML应用程序通常有以下两种加载QQmlEngine:
- 1、通过 QQuickView 搭配Item加载 QML 文件,
- 2、创建一个 QQmlApplicationEngine,并搭配Window 加载 QML 文件
这类联合了QQmlEngine和QmlComponent去加载单独的QML文件。他还向QML提供了应用程序的功能,这个应用程序的功能能够让C++与QML混合编程,使用C++控制业务逻辑,用QML做界面,与QQuickView不同的是,QQmlApplicationEngine不会自动创建一个根窗口,如果使用可视化项目,需要将他们放入Window里。
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView viewer; viewer.setResizeMode(QQuickView::SizeRootObjectToView); viewer.setSource(QUrl("qrc:///main.qml")); viewer.show(); return app.exec(); }
一般的,应用程序会初始化一个QQmlEngine类作为QML引擎,然后使用QQmlComponent对象加载QML文档,QML引擎会提供一个默认的QQmlContext对象作为顶层上下文(可有QQmlEngine::rootContext()获取),用来执行QML文档中定义的函数和表达式,如果加载QML文档没有任何错误,QML文档定义的对象层次将使用QQmlcomponent的create创建,当所有对象创建完毕时则会将控制权交给Qt的事件循环系统。
三、运行时的C++类
3.1 QQmlEngine
QQmlEngine类提供了一个QML引擎,用于管理由QML文档定义的对象层次结构,QML引擎提供了一个默认的QML上下文也就是根上下文,它提供了表达式的执行环境。
QQmlApplicationEngine engine; engine.addImportPath(path + "/CommonControls"); engine.load(QUrl(QStringLiteral("qrc:/LoginView.qml")));
3.2 QQmlContext
QQmlContext提供了对象实例化和表达式执行所需的运行时上下文,所有的对象都需要在一个特定的上下文中实例化,所有表达式都要在一个特定的上下文中执行。
3.3 QQmlComponent
QML文档定义的对象类型可以在运行时使用QQmlComponent类型进行实例化,既可以使用C++直接创建,也可以通过Qt.createComponent()函数在QML代码中创建。
QQmlComponent封装了QML组件的定义,可以用于加载QML文档:
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QQmlEngine engine; QQmlComponent component(&engine, QUrl::fromLocalFile("../myqml/main.qml")); QObject *myObject = component.create(); QQuickItem *item = qobject_cast<QQuickItem*>(myObject); qreal width = item->width(); qDebug() << width; return a.exec(); }
3.4 QQmlExpression
QQmlExpression允许客户端在C++中,利用一个特定的QML上下文执行JavaScript表达式,表达式的执行结果以QVariant的形式返回,并且遵循QML引擎确定的转换规则。