使用生成器

本主题介绍了如何使用 QtIVI 生成器。

简介

生成器是一个 Python 脚本,可以手动运行或使用 qmake 集成。此脚本使用 QFace 作为自动生成框架,解析 IDL 文件,生成领域模型(类似于抽象语法树(AST)),然后将它馈送到生成器。根据要生成的项目类型,指定不同的 格式

命令行参数

要运行生成,使用以下命令

$$[QT_HOST_BINS]/ivigenerator/generate.py --format=backend_simulator interface.qface out_dir

选项和参数如下所示

选项/参数描述
--reload / --no-reload [可选]指定生成器是否应跟踪 IDL 文件中的更改并在飞行中更新输出;默认为 --no-reload
-f--format可以是以下值之一
  • 前端
  • qmlplugin
  • backend_simulator
  • backend_qtro
  • server_qtro
  • <folder>
-A, --annotations <annotation-file>将提供的注解文件与 QFace 文件和隐含的注解文件中已有的注解合并。这些文件根据传递给生成器的顺序合并。在 YAML 文件中提供重复的键将覆盖之前设置的值。此选项可以使用多次。有关更多信息,请参阅 合并注解
-I, --import <import-path>将给定的路径添加到导入路径列表中。递归扫描此列表中的所有目录以查找 QFace 文件。然后使用找到的 QFace 文件来解决导入模块所需的信息;这与 C++ 包含路径的工作方式类似。
IDL 源文件的路径或路径。如果有多个条目,则每个条目都进行处理。如果提供目录路径,则扫描该目录以查找 IDL 文件。
outputdir生成文件的目标文件夹。
--help显示选项并退出。

目前,基于 --format 值,生成器可以使用给定的 IDL 文件生成多种类型的多个项目

项目类型描述
前端 使用来自 qtivicore 的基类和 动态后端系统 生成 API。
qmlplugin生成一个 C++ QML 插件,该插件在 QML 中注册前端中的所有类型。
后端模拟器 为首先由 前端 选项生成的 API 生成一个模拟后端。此后端充当模拟实现。
后端_qtro 根据前端选项生成的API,首先生成基于QtRemoteObjects的后端客户端。此客户端连接到后端服务器。
服务器_qtro 根据前端选项生成的API,首先生成基于QtRemoteObjects的后端服务器桩。
文件夹路径在文件夹内部使用模板。一个与文件夹同名YAML文件应提供文件夹中模板文件的列表。如果您希望编写自己的模板,这非常有用。有关更多详细信息,请参阅生成YAML

配置生成器

生成器的Python脚本解析输入文件并创建域模型。然后,将此域模型作为上下文传递给Jinja模板引擎。使用生成YAML文件指定要生成的文件。之后,您可以使用注释YAML文件向IDL文件添加更多信息,这是针对特定生成器的。

生成YAML

在创建域模型树之后,遍历此树,并将域模型对象树的每个叶子节点(模块、接口、结构等)传递给由配置文件定义的特定Jinja模板。

生成YAML文件定义了用于生成哪些文件的模板。假设您想为您的域模型中的每个模块生成一个头文件。但是,一个模块可以具有多个接口,因此,您希望为每个接口和结构使用不同的头文件。在这种情况下,生成YAML文件定义了一组规则来指定使用哪个模板文件以及如何命名它们。

此YAML文件必须有以下结构

frontend:
    module:
        documents:
            - "{{module.module_name|lower}}plugin.h": "plugin.h.tpl"
    interface:
        documents:
            - '{{interface|lower}}backend.h': 'backend.h.tpl'

对于每个实体,都有一个当在域模型树中遍历此实体时必须调用的一组模板。在此,YAML文件定义了一个文档列表,需要生成所有模块和接口的列表。每个列表条目由两部分组成;第一部分是需要创建的文件名,如Jinja模板语言中指定的格式。模板名称中使用的对象属性的值经过处理和替换后被替换到模板中,从而形成了创建最终文件名的名称。第二部分是使用模板的名称。对于IVI生成器,您必须指定三种实体的规则:模块、接口和结构。有关更多详细信息,请参阅QFace规则基础生成文档

注释YAML

目前,不使用IDL本身来表达接口描述的所有方面。例如,没有语言构造可以定义属性默认值或属性可以接受的值的范围。但是,这可以通过一种称为注释的机制来实现。注释提供自由和灵活性来表达任何概念和构造。

下面的代码片段显示了在IDL中使用注释的一个示例。在这里,我们定义了一个带区域的接口,并指定了它的ID。

@config: {zoned: true, id: "org.qt-project.qtivi.ClimateControl/1.2"}

将所有注释放置在主要IDL文件中是没有意义的。例如,您可能需要定义自动测试代码生成的一些方面。这样的注释可以放在与主要IDL文件配对的,同名YAML文件中。在解析阶段QFace自动提取此文件并将YAML文件中指定的注释与IDL文件中定义的注释合并。

由于附加的 YAML 文件总是自动选取,因此它不适用于某些特定项目所需的注释,例如在生成后端插件时。对于这种情况,您可以向生成器传递多个额外的注释 YAML 文件。

QtIvi 中,以下注释用于定义 IDL

标签位置对象类型目的
@config: {interfaceBuilder: "FunctionName"}
主 IDL 文件模块声明一个函数,该函数会在插件中调用以为每个接口生成实例。该函数接受插件实例的指针,并返回一个 QVector<QIviFeatureInterface *>。接口的生成顺序应与 Plugin::interfaces() 定义的顺序相同。使用此标签来实例化生成插件接口类的派生类。
@config: {zoned: true}
主 IDL 文件接口告诉生成器接口是否分区。使用此标签定义后端功能接口是从 QIviZonedFeatureInterface 还是 QIviFeatureInterface 派生的。
@config: {id: "org.qt.project.qtivi.ClimateControl/1.0"}
主 IDL 文件接口定义接口 ID,这是一个由 QtIvi 服务管理器使用的字符串,用于将前端接口与其后端实现连接起来。有关更多信息,请参阅 动态后端系统
@config: {getter_name: "isHeaterEnabled"}
主 IDL 文件属性重写默认获取方法名称。对于布尔属性很有用,例如属性的获取器应为 'isEnabled' 而不是默认的。
@config: {setter_name: "setHeaterEnabled"}
主 IDL 文件属性重写默认设置方法名称。
@config: {qml_name: "ClimateControl"}

@config: {qml_type: "ClimateControl"}
主 IDL 文件模块,接口定义接口或模块在该 QML 中应使用的名称。对于接口,它是用于将接口导出到 QML 中的名称。对于模块,它定义了完整模块的 URI。URI 的最后一部分也用于将所有枚举导出到 QML 中的单例。

不属于接口描述逻辑部分,而是用于指定额外信息的注释,置于附加的 YAML 文件中。以下是用于定义生成后端模拟各种方面的注释列表

标签位置对象类型目的
config_simulator:
    simulationFile: ":/qrc/simulation.qml"
附加的 YAML 文件模块定义模拟后端应加载的哪个模拟 QML 文件。提供的片段从资源系统加载 QML 文件,开发人员需要将其嵌入。
config_simulator:
    zones: [ FrontLeft,
             FrontRight,
             Rear ]
附加的 YAML 文件接口定义后端模拟应该支持的区域列表。
config_simulator:
default:
    AirflowDirection.Floor |
    AirflowDirection.Dashboard
附加的 YAML 文件属性定义模拟后端返回的属性初始值。

对于分区属性,可以将区域映射到默认值。映射的默认键是 "="。

config_simulator:
default: {
    FrontLeft: 21.0,
    FrontRight: 22.5, =: 0.0
}
config_simulator:
minimum: 10
附加的 YAML 文件属性定义整型和实型属性的最低值;模拟后端生成的代码验证值。
config_simulator:
maximum: 10
附加的 YAML 文件属性定义整型和实型属性的最高值;模拟后端生成的代码验证值。
config_simulator:
range: [10, 20]
附加的 YAML 文件属性定义整型和实型属性的值范围;模拟后端生成的代码验证值。
config_simulator:
domain: {10, 20, 30}
附加的 YAML 文件属性定义属性的可能的值;模拟后端生成的代码验证值。

生成项目的结构

在生成器输出目录中,首先创建一个新的子文件夹,将其命名为模块 ID。所有生成的文件都放置在这个文件夹中。下表描述了为前端和后端生成的文件。

前端

基于 动态后端系统 生成 QML 友好的 C++ API。

文件名目的
global.h具有全局 EXPORT 定义的标准文件。
module.h/cpp定义模块类的文件,用于模块全局变量和类型。
module_enum.qdocinc所有枚举值的文档,可由 qdoc 包含。
modulefactory.h/cpp定义模块工厂类的文件,用于所有结构体的工厂方法。
`.pri`一个包含所有生成文件的标准的 Qt .pri 文件。使用这个 .pri 文件将生成文件包含到 qmake 项目中。
qml/{{module|qml_type|replace('.', '/')}}/plugins.qmltypesQtCreator 中使用的 QML 代码补全文件。
backendinterface.h/cpp定义接口的文件需要由功能的后端实现来完成。
.h/cpp功能的原生实现,已准备好从 QML 中使用。
_p.h前端实现的私有部分。
.h/cpp使用 Q_GADGET 作为 QML 的实现结构。

QML 插件

生成一个 C++ QML 插件,该插件在 QML 中注册前端中的所有类型。

文件名目的
plugin.cppC++ QML 插件类。
`.pri`一个包含所有生成文件的标准的 Qt .pri 文件。使用这个 .pri 文件将生成文件包含到 qmake 项目中。
plugins.qmltypesQtCreator 中使用的 QML 代码补全文件。
qmldirQML 配置文件,用于将插件注册到 QML 插件系统中。

后端模拟器

提供使用 QIviSimulationEngine 的模拟器后端,以实现在 QML 文件中的模拟行为。

文件名目的
plugin.h/cpp定义实现 QtIvi 后端插件的文件,该插件实现了 QIviServiceInterface
.json包含需要由 Qt 插件系统使用的暴露功能接口标识符的文件。
`.pri`一个包含所有生成文件的标准的 Qt .pri 文件。使用这个 .pri 文件将生成文件包含到 qmake 项目中。
_simulation.qml加载特定接口的 QML 模拟文件的 QML 模拟文件。
_simulation_data.json从配置模拟器注解中导出的模拟数据。
.qrc包含 QML 和 JSON 文件的 Qt 资源文件。
qml/{{module|qml_type|replace('.', '/')}}/plugins.qmltypesQtCreator 中使用的 QML 代码补全文件。
qml/{{module|qml_type|replace('.', '/')}}/simulation/plugins.qmltypes"QtCreator 中用于模拟 API 的 QML 代码补全文件。
backend.h/cpp包含模拟后端实现的文件。
Simulation.qml特定接口的 QML 模拟文件。

QtRemoteObjects 后端

只有当 qmake 发现 QtRemoteObjects 模块时,后端_qtro 模板才可用。产生的代码只包含继承的源类和建立连接的代码。开发者必须实现实际的后端逻辑。

文件名目的
plugin.h/cpp定义实现 QtIvi 后端插件的文件,该插件实现了 QIviServiceInterface
.json包含需要由 Qt 插件系统使用的暴露功能接口标识符的文件。
`.pri`一个包含所有生成文件的标准 Qt .pri 文件。使用此 .pri 文件将生成文件包含到 QMake 项目中。还包括 .rep 文件到项目中,并调用远程对象编译器。
backend.h/cpp包含远程对象后端实现的文件。建立连接并初始化远程对象副本。
.repQt 的 副本编译器 的输入文件,以生成副本类的代码。
pagingmodel.repQt 的 副本编译器 的输入文件,以生成所有模型的副本类代码。

QtRemoteObjects 服务器

只有当 qmake 发现 QtRemoteObjects 模块时,服务器_qtro 模板才可用。产生的代码只包含源类代码,用于继承和代码,用于建立连接。开发者必须实现实际的后端逻辑。

文件名目的
core.h/cpp建立连接并开始源对象的远程传输的代码。
`.pri`一个包含所有生成文件的标准 Qt .pri 文件。使用此 .pri 文件将生成文件包含到 QMake 项目中。还包括 .rep 文件到项目中,并调用远程对象编译器。
.repQt 的 副本编译器 的输入文件,以生成源类代码。
pagingmodel.repQt 的 副本编译器 的输入文件,以生成所有模型的副本类代码。

QtRemoteObjects 模拟服务器

仅当qmake找到QtRemoteObjects模块时,server_qtro_simulator模板才可用。生成的代码包含一个完整实现的服务器,使用与backend_simulator模板相同的实现,该模板使用QIviSimulationEngine在QML中实现模拟行为。

文件名目的
_simulation.qml加载特定接口QML模拟文件的QML模拟文件。
_simulation_data.json从配置模拟器注解中导出的模拟数据。
.qrc包含QML和JSON文件的Qt资源文件。
qml/{{module|qml_type|replace('.', '/')}}/plugins.qmltypesQtCreator 中使用的 QML 代码补全文件。
qml/{{module|qml_type|replace('.', '/')}}/simulation/plugins.qmltypesQtCreator 中用于模拟 API 的 QML 代码补全文件。
core.h/cpp建立连接并开始源对象的远程传输的代码。
main.cpp主文件。
`.pri`一个包含所有生成文件的标准 Qt .pri 文件。使用此 .pri 文件将生成文件包含到 QMake 项目中。还包括 .rep 文件到项目中,并调用远程对象编译器。
.repQt 的 副本编译器 的输入文件,以生成源类代码。
adapter.h/cppQtRemoteObjects适配器类,用于后端实现。
pagingmodel.repQt 的 副本编译器 的输入文件,以生成所有模型的副本类代码。
backend.h/cpp包含模拟后端实现文件的文件。
Simulation.qml特定接口的 QML 模拟文件。

©2020年Qt公司有限公司。此处包含的文档贡献者的版权所有。本文件提供的文档经自由软件基金会发布的GNU自由文档许可证版本1.3许可。Qt及其相应商标是芬兰及其它国家Qt公司的注册商标。所有其他商标均归其各自所有者所有。