QML脚本编译器

QML脚本编译器将QML和JavaScript文件中的函数和表达式编译成字节码,该字节码可以被QML引擎解释或即时编译。

此外,它将QML文件中的一些函数和表达式编译成C++代码,受JavaScript特性的限制。它为可完全分析的函数生成C++代码。以下流程图解释了编译的工作流程。

QML脚本编译器有两种版本。一个是qmlcachegen,它是Qt Quick编译器的一部分。另一个是qmlsc,它是仅限商业附加组件Qt Quick编译器扩展的一部分。

qmlcachegen

qmlcachegen使用元对象系统,并生成查找并将它们存储在中央位置,即编译单元。编译单元包含文档结构的表示,每个函数和表达式的紧凑字节码表示,以及编译器完全理解的函数和绑定的原生代码。编译单元中的字节码可以由QML引擎使用,以避免重新编译并加快执行。

qmlsc

qmlsc则通过提供两种额外的模式来扩展qmlcachegen的基本功能。

静态模式

在静态模式下,qmlsc假定公开给C++的所有类型的属性不会被派生类型所屏蔽。它消除了屏蔽检查机制,允许更多JavaScript代码被编译成C++,并最终生成更快的代码。

要在qmlsc中启用静态模式,您应通过QT_QMLCACHEGEN_ARGUMENTS--static传递给qt_add_qml_module

qt_add_qml_module(someTarget
...
)

set_target_properties(someTarget PROPERTIES
    QT_QMLCACHEGEN_ARGUMENTS "--static"
)

警告:如果QML文档中存在任何属性被屏蔽,qmlsc静态模式生成的代码将无效。

直接模式

在直接模式下,qmlsc假定您在QML代码中使用的所有C++类型都是可用的,并且可以作为C++头文件将它们包含到生成的代码中。然后生成的代码通过直接调用这些头文件中的获取器、设置器和可调用函数来访问或修改属性,这使得执行速度更快。这意味着您必须在CMake中链接私有Qt API。

警告:私有Qt API经常更改。您需要为每个新版本重新编译Qt。

警告:如果类型仅在插件中定义或没有头文件,则无法在直接模式下使用它。

要启用直接模式,应考虑以下因素

  • 您应通过 QT_QMLCACHEGEN_ARGUMENTS 传递 --direct-callsqt_add_qml_module
    qt_add_qml_module(someTarget
    ...
    )
    
    set_target_properties(someTarget PROPERTIES
        QT_QMLCACHEGEN_ARGUMENTS "--direct-calls"
    )
  • 请链接所有相关的私有 Qt 模块而不是它们的公共版本。
    qt_add_qml_module(someTarget
    ...
    )
    
    target_link_libraries(someTarget PRIVATE
        Qt::QmlPrivate
        Qt::QuickPrivate
        ...
    )
  • 不要将 PLUGIN_TARGET 设置为与支持库目标相同。
    # direct mode will not function in this setup.
    qt_add_qml_module(someTarget
    PLUGIN_TARGET someTarget
    ...
    )

将 JavaScript 编译为 C++ 时存在的限制

许多 JavaScript 构造无法有效地用 C++ 表示。QML 脚本编译器会跳过包含此类结构的函数的 C++ 代码生成,仅生成字节码以供解释或通过即时编译器执行。最常见的 QML 表达式相对简单:QObjects 上的值查找、算术、简单的 if/else 或循环结构。它们可以轻松地在 C++ 中表示,并且这样做可以使您的应用程序运行更快。

© 2024 Qt 公司有限公司。此处包含的文档贡献是各自所有者的版权。本提供的文档是根据由自由软件基金会发布的免费文档许可协议版本 1.3 许可的。Qt 及相关标志 是芬兰及其它国家的 Qt 公司的商标。所有其他商标均为其各自所有者的财产。