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 文件
  QQmlApplicationEngine提供了从一个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();
}

  使用QQuickView显示QML文档,对窗口的控制权(比如设置窗口标题、Icon、窗口的最小尺寸等)在C++代码;而使用QQmlApplicationEngine加载以Window为根对象的QML文档,QML文档则拥有窗口的完整控制权,可以直接设置标题、窗口尺寸等属性。
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引擎确定的转换规则。

相关推荐