qt_add_qml_module

此命令自 Qt 6.2 开始引入。

概述

qt_add_qml_module(
    target
    URI uri
    [VERSION version]
    [PAST_MAJOR_VERSIONS ...]
    [STATIC | SHARED]
    [PLUGIN_TARGET plugin_target]
    [OUTPUT_DIRECTORY output_dir]
    [RESOURCE_PREFIX resource_prefix]
    [CLASS_NAME class_name]
    [TYPEINFO typeinfo]
    [IMPORTS ...]
    [OPTIONAL_IMPORTS ...]
    [DEFAULT_IMPORTS ...]
    [DEPENDENCIES ...]
    [IMPORT_PATH ...]
    [SOURCES ...]
    [QML_FILES ...]
    [RESOURCES ...]
    [OUTPUT_TARGETS out_targets_var]
    [DESIGNER_SUPPORTED]
    [FOLLOW_FOREIGN_VERSIONING]
    [NAMESPACE namespace]
    [NO_PLUGIN]
    [NO_PLUGIN_OPTIONAL]
    [NO_CREATE_PLUGIN_TARGET]
    [NO_GENERATE_PLUGIN_SOURCE]
    [NO_GENERATE_QMLTYPES]
    [NO_GENERATE_QMLDIR]
    [NO_LINT]
    [NO_CACHEGEN]
    [NO_RESOURCE_TARGET_PATH]
    [NO_IMPORT_SCAN]
    [ENABLE_TYPE_COMPILER]
    [TYPE_COMPILER_NAMESPACE namespace]
    [QMLTC_EXPORT_DIRECTIVE export_macro]
    [QMLTC_EXPORT_FILE_NAME header_defining_export_macro]

)

如果禁用了无版本命令,请使用 qt6_add_qml_module() 代替。它支持与该命令相同的参数集。

请参见无版本命令,以及定义 QML 模块的示例,例如 构建 QML 应用程序构建可重用的 QML 模块

请参见 QT_QML_GENERATE_QMLLS_INI 来配置您的项目,以便将有关 QML 模块的信息暴露给 QML 语言服务器

描述

此命令定义了一个 QML 模块,它可以由 C++ 源码、.qml 文件或两者组合而成。它确保提供了基本模块详情,并保持一致性。它还设置和协调像缓存的 .qml 源码编译、资源嵌入、代码检查和自动生成一些关键模块文件等事务。

目标结构

QML 模块的构建结构有几种方式。以下场景是典型的安排:

单独的后备和插件目标

这是大多数 QML 模块推荐的安排。所有模块的功能都实现在一个名为 backing 的目标中,这是给定的第一个命令参数。C++ 源码、.qml 文件和资源应全部添加到后备目标中。后备目标是一个库,应安装在与项目中定义的任何其他库相同的位置。

在创建后备目标下的源目录结构应与 QML 模块的目标路径(目标路径是模块的 URI,点用正斜杠替换)相匹配。如果源目录结构与目标路径不匹配,qt_add_qml_module() 将发出警告。

以下示例显示了具有 URI `MyThings.Panels` 的 QML 模块的适当源目录结构。在显示的 `CMakeLists.txt` 文件中对 qt_add_qml_module() 的调用是合适的。

src
 +-- MyThings
      +-- Panels
           +-- CMakeLists.txt

与 QML 模块相关联的一个单独的 插件 目标。在应用程序已经没有链接到后备目标时,它在运行时用于动态加载模块。插件目标也将是一个库,通常安装在与模块的 qmldir 文件相同的目录中。

插件目标应理想地仅包含插件类的简单实现。这允许在 qmldir 文件中将插件指定为可选的。其他目标可以直接链接到后置目标,这样在运行时无需插件,可以提高加载性能。默认情况下,将自动生成并添加到插件目标的 C++ 源文件来定义最小插件类。对于需要自定义插件类实现的 QML 模块,可能需要使用 NO_GENERATE_PLUGIN_SOURCE 和通常 NO_PLUGIN_OPTIONAL 选项。

如果未指定 NO_PLUGIN,则还生成静态的 QML 插件。导入此类 STATIC QML 模块的目标也需要显式链接到相应的 QML 插件。

注意:在静态链接时,可能需要使用 Q_IMPORT_QML_PLUGIN 以确保 QML 插件正确链接。

无后置目标的插件目标

QML 模块可以定义得用插件目标作为自己的后置目标。在这种情况下,模块必须在运行时动态加载,不能由其他目标直接链接。为了创建这种安排,必须使用 PLUGIN_TARGET 关键字,并将 target 重复作为插件目标名称。例如

qt_add_qml_module(someTarget
    PLUGIN_TARGET someTarget
    ...
)

虽然这种安排在部署上可能略显简单,但由于可能更好的加载性能,应尽可能选择使用单独的后置目标。

作为 QML 模块的可执行

可执行目标可以作为 QML 模块的后置目标。在这种情况下,将没有插件库,因为 QML 模块将始终作为应用程序的一部分直接加载。当使用可执行文件作为后置目标时,qt_add_qml_module() 命令将检测到并自动禁用创建单独插件。不要在使用这种安排时使用任何名为 PLUGIN 的选项。

当使用可执行文件作为后置目标时,源目录结构预计不会与 QML 模块的目标路径匹配。有关编译资源的目标路径差异,请参阅 缓存编译的 QML 源文件

自动生成 qmldir 和 typeinfo 文件

默认情况下,将为定义的 QML 模块自动生成 qmldir 文件和类型信息文件。这些文件的正文由给此命令的各种参数以及添加到后置目标的源和 .qml 文件确定。OUTPUT_DIRECTORY 参数确定 qmldir 和类型信息文件将写入的位置。如果 QML 模块具有插件,该插件也将与 qmldir 文件同一目录中创建。

若使用静态构建的Qt,在CMake配置运行期间,将扫描支持目标的.qml文件,以确定模块使用的导入并设置链接关系(可以通过提供NO_IMPORT_SCAN关键字来禁用此功能)。当向模块添加或删除.qml文件时,CMake通常会自动重新运行,相关文件将被重新扫描,因为CMakeLists.txt文件已被修改。在开发过程中,现有的.qml文件可能会添加或删除导入或类型。单独来看,这不会导致CMake自动重新运行,因此您应显式重新运行CMake,以强制重新生成qmldir文件,并更新任何链接关系。

在构建时扫描支持目标的C++源代码,以生成类型信息文件和注册相关类型的C++文件。生成的C++文件将自动添加到支持目标作为源代码。这需要在目标上启用AUTOMOC。项目负责确保这一点,通常通过在调用qt_add_qml_module()之前将CMAKE_AUTOMOC变量设置为TRUE,或者通过传递一个已设置AUTOMOC目标属性为TRUE的现有目标。在目标上禁用AUTOMOC不是错误,但项目随后负责处理后果。这可能包括需要手动生成类型信息文件而不是允许它自动生成而缺少详细信息,并添加C++代码来注册类型。

项目应优先考虑在可能的情况下使用自动生成的类型信息和qmldir文件。它们更容易维护,并且不会像手动编写的文件那样容易出错。尽管如此,对于需要自己提供这些文件的项目,可以禁用自动生成。使用NO_GENERATE_QMLDIR选项禁用qmldir的自动生成,使用NO_GENERATE_QMLTYPES选项禁用类型信息和C++类型注册的自动生成。如果自动生成的类型信息文件可以接受,但项目希望为该文件使用不同的名称,则可以使用TYPEINFO选项覆盖默认名称(但这通常不需要)。

缓存编译后的QML源代码

通过QML_FILES参数添加到模块中的所有.qml.js.mjs文件将编译成字节码,并直接缓存到支持目标中。这提高了模块的加载时间性能。原始未编译的文件也存储在支持目标的资源中,因为这些文件在某种情况下可能仍然需要由QML引擎使用。

每个文件的资源路径由其相对于当前源目录的路径(CMAKE_CURRENT_SOURCE_DIR)确定。此资源路径将附加到一个由将RESOURCE_PREFIX和目标路径连接而成的前缀中(但请参阅NO_RESOURCE_TARGET_PATH了解对此的例外)。

如果QTP0001策略设置为NEW,则RESOURCE_PREFIX默认为/qt/qml/,这是QML引擎的默认导入路径。这确保了模块被放入QML导入路径中,并且无需进一步设置即可找到。

通常,项目应该旨在将.qml文件放置在与资源相同的相对位置。如果.qml文件位于与其期望的资源路径不同的相对目录中,那么需要在资源中显式指定其位置。这是通过设置QT_RESOURCE_ALIAS源文件属性来完成的,这个属性必须在添加.qml文件之前设置。例如

set_source_files_properties(path/to/somewhere/MyFrame.qml PROPERTIES
    QT_RESOURCE_ALIAS MyFrame.qml
)

qt_add_qml_module(someTarget
    URI MyCo.Frames
    RESOURCE_PREFIX /my.company.com/imports
    QML_FILES
        path/to/somewhere/MyFrame.qml
        AnotherFrame.qml
)

在上面的例子中,目标路径将是MyCo/Frames。在考虑源文件属性后,两个.qml文件将在以下资源路径找到

  • /my.company.com/imports/MyCo/Frames/MyFrame.qml
  • /my.company.com/imports/MyCo/Frames/AnotherFrame.qml

在极少数情况下,如果您想覆盖qlcachegen程序自动选择的情况,您可以在模块目标上设置QT_QMLCACHEGEN_EXECUTABLE目标属性。例如

set_target_properties(someTarget PROPERTIES
    QT_QMLCACHEGEN_EXECUTABLE qmlcachegen
)

这明确选择了qmlcachegen作为使用的程序,即使有更好的替代方案。

此外,您可以通过设置QT_QMLCACHEGEN_ARGUMENTS选项,向qmlcachegen传递额外的参数。特别是--only-bytecode选项将关闭将QML脚本代码编译为C++的编译。例如

set_target_properties(someTarget PROPERTIES
    QT_QMLCACHEGEN_ARGUMENTS "--only-bytecode"
)

另一个重要的参数是--direct-calls。如果您安装了Qt Quick Compiler Extensions,则可以使用它来启用QML脚本编译器的直接模式。如果没有安装扩展,该参数将被忽略。它有一个简写的名字叫QT_QMLCACHEGEN_DIRECT_CALLS

set_target_properties(someTarget PROPERTIES
    QT_QMLCACHEGEN_DIRECT_CALLS ON
)

最后,可以使用--verbose参数来查看qmlcachegen的诊断输出

set_target_properties(someTarget PROPERTIES
    QT_QMLCACHEGEN_ARGUMENTS "--verbose"
)

设置此标志后,qmlcachegen将输出它无法编译为C++的每个函数的警告。其中一些警告将指向您的QML代码中的问题,还有一些会告诉您QML语言的一些功能尚未在C++代码生成器中实现。在这两种情况下,qmlcachegen仍将为这些函数生成字节码。如果您只想查看您的QML代码中的问题,您应该使用qmllint及其为其生成的目标。

QML源代码的Linting

如果通过关键字QML_FILES或在稍后的对qt_target_qml_sources()的调用将任何.qml文件添加到模块中,将自动创建一个单独的linting目标。该linting目标的名称将是target后跟_qmllint。还提供了一个名为all_qmllint的目标,它依赖于所有单个*_qmllint目标,作为便利工具。

.js文件命名约定

预期作为组件引用的JavaScript文件名应该以大写字母开头。

或者,您可以使用小写文件名,并将源文件属性QT_QML_SOURCE_TYPENAME设置为您期望的类型名。

单例

如果QML模块有提供单例类型的.qml文件,则需要将这些文件的QT_QML_SINGLETON_TYPE源属性设置为TRUE,以确保将singleton命令写入到qmldir文件中。这必须在与单例属于的模块创建之前完成。

有关如何设置QT_QML_SINGLETON_TYPE属性的示例,请参阅qt_target_qml_sources()

使用QML类型编译器将QML编译为C++

注意: QML类型编译器 qmltc 不能保证生成的C++代码在过去的或未来的版本(包括补丁版本)之间保持API、源代码或二进制兼容性。此外,使用Qt的QML模块编译的qmltc应用需要链接到私有Qt API。见使用qmltc编译QML代码

如果一个QML模块包含.qml文件,可以使用qmltc将其编译为C++。与字节码编译不同,您需要通过ENABLE_TYPE_COMPILER参数显式启用qmltc。在这种情况下,QML_FILES下指定的.qml文件将被编译。以.js.mjs结尾的文件将被忽略,因为qmltc不编译JavaScript代码。另外,带有QT_QML_SKIP_TYPE_COMPILER源文件属性的文件也会被跳过。

默认情况下,qmltc为给定的.qml文件创建小写的.h.cpp文件。例如,Foo.qml将被编译成foo.hfoo.cpp

创建的C++文件放置在BINARY_DIR.qmltc/<目标>子目录中。然后这些文件将自动添加到目标源,与其他源文件一起编译为Qt C++代码。

处理QML_FILES时,会尊重以下源文件属性

  • QT_QMLTC_FILE_BASENAME:使用此源文件属性来指定非默认的.h和.cpp文件名,这在解决冲突的文件名时可能很有用(想象一下您正在编译main.qml,但main.h已经存在,所以#include "main.h"可能不会如您所预期的那样工作)。QT_QMLTC_FILE_BASENAME预期为一个文件名(不包含扩展名),因此任何前面的目录都被忽略。与默认行为不同,QT_QMLTC_FILE_BASENAME不会被转换为小写。
  • QT_QML_SKIP_TYPE_COMPILER:使用此源文件属性来指定必须由qmltc忽略的QML文件。

参数

必需参数

target指定了QML模块的后备目标名称。默认情况下,如果Qt被构建为共享库,则将其创建为共享库,否则创建为静态库。可以使用STATICSHARED选项显式覆盖此选择。

每个QML模块都必须定义一个URI。它应该指定为点分URI表示法,例如QtQuick.Layouts。每个段必须是有效的ECMAScript标识符名称。这意味着,例如,段不能以数字开头,并且不能包含-(减号)字符。由于URI将被转换为目录名,因此应将其限制为拉丁字母的字母数字字符、下划线和点。其他QML模块可以使用此名称在导入语句中导入模块。使用URI在生成的qmldir文件的module行中使用。将使用URI通过将点替换为正斜杠来形成目标路径

有关模块URI的更深入讨论,请参阅已识别模块

版本

QML模块还可以定义以Major.Minor形式的VERSION,其中MajorMinor都必须是整数。还可以附加一个可选的.Patch组件,但将被忽略。还可以在PAST_MAJOR_VERSIONS关键字之后(见下文)提供模块提供的早期主要版本的列表。有关版本编号的更深入讨论,请参阅已识别模块,有关注册早期主要版本的说明,请参阅注册早期主要版本,以及有关保持模块版本同步的说明,请参阅保持模块版本同步

如果您不需要版本号,应省略VERSION参数。它默认为最高版本。QML模块的内部版本管理存在一些基本缺陷。您应使用外部包管理机制来管理您QML模块的不同版本。

向模块添加源和资源

SOURCES指定要添加到目标回退的非QML源列表。它作为一个方便的工具,等价于使用内置的target_sources() CMake命令将源代码添加到回退目标。

QML_FILES列出了模块的.qml.js.mjs文件。这些文件将被自动编译成字节码并嵌入到回退目标中,除非指定了NO_CACHEGEN选项。即使在指定了NO_CACHEGEN的情况下,未编译的文件也始终存储在回退目标的嵌入式资源中。除非指定了NO_LINT选项,否则未编译的文件还将通过一个单独的自定义构建目标由qmllint处理。默认情况下,这些文件也将用于填充生成的qmldir文件中的类型信息。NO_GENERATE_QMLDIR可用于禁用自动生成qmldir文件。通常应该避免这种情况,但在项目需要提供自己的qmldir文件的情况下,可以使用此选项。

注意:有关在调用qt_add_qml_module()之后如何添加qmlfiles的更多详细信息,请参阅qt_target_qml_sources()。例如,您可能会根据条件语句表达式添加文件,或者从只有满足某些条件时才会添加的子目录添加文件。此外,使用qt_target_qml_sources()添加的文件还可以指定是否要跳过清理、字节码编译qmldir文件生成。

RESOURCES列出了模块所需的其他文件,例如从QML代码中引用的图像。这些文件将被添加为编译内资源(有关它们将位于的基点的说明,请参阅RESOURCE_PREFIX)。如果需要,可以通过设置QT_RESOURCE_ALIAS源属性来控制它们的相对位置,就像对于.qml文件一样(参见缓存编译的QML源)。

RESOURCE_PREFIX旨在封装项目命名空间,对于项目定义的所有QML模块通常相同。应选择以确保不会与其他项目使用的资源前缀或任何其他可能使用它的项目冲突。一个不错的选择是将项目所属组织的域名包含在内。一个常见的做法是在域名后附加/imports来形成资源前缀。例如

qt_add_qml_module(someTarget
    RESOURCE_PREFIX /my.company.com/imports
    ...
)

将各种文件添加到编译内资源时,它们会被放置在通过连接 RESOURCE_PREFIX 和目标路径形成的路径下。对于后端目标是可执行文件的特殊情况,可能希望将模块的 .qml 文件和其他资源直接放置在 RESOURCE_PREFIX 之下。这可以通过指定 NO_RESOURCE_TARGET_PATH 选项来实现,但该选项只能在后端目标是可执行文件时使用。

注册过去的重大版本

PAST_MAJOR_VERSIONS 包含模块提供的附加主版本列表。对于这些版本中的每一个以及每个没有 QT_QML_SOURCE_VERSIONS 设置的 QML 文件,将生成一个额外的条目放入 qmldir 文件中,以指定额外版本。此外,生成的模块注册代码将在 C++ 端使用 qmlRegisterModule() 注册过去的重大版本。你的 QML 模块的模块注册代码将自动生成,除非你指定 NO_GENERATE_QMLTYPES(但强不建议使用此选项)。使用 PAST_MAJOR_VERSIONS 会给你的模块导入增加一些开销。你应该尽可能少地增加模块的主版本。一旦你可以信任所有导入该模块的 QML 文件都省略了版本号,你就可以安全地省略 PAST_MAJOR_VERSIONS。然后,所有的 QML 文件将导入你的模块的最新版本。如果你必须支持带有版本号的导入,请考虑只支持有限数量的过去的主版本号。

声明模块依赖

IMPORTS 提供了一个其他 QML 模块的列表,这些模块将被此模块导入。此处列出的每个模块都将被添加到生成的 qmldir 文件中的 import 条目。如果 QML 文件导入了此模块,它也将导入 IMPORTS 下列出的所有模块。可以指定版本,例如 QtQuick/2.0。省略版本将导入可用的最高版本。你可以仅指定主版本,如 QtQuick/2。在这种情况下,将导入给定主版本中可用的最高次要版本。最后,版本可以是 auto (如 QtQuick/auto)。如果指定了 auto,则将当前模块导入的版本传递给要导入的模块。给定一个模块 YourModule 中的条目 QtQuick/auto,如果 QML 文件指定 import YourModule 3.14,这将导致导入 3.14 版本的 QtQuick。对于遵循共同版本方案的相关模块,你应该使用 auto

OPTIONAL_IMPORTS 提供了一个列表,表示在此模块运行时可能会导入的其他 QML 模块。QML 引擎在导入当前模块时不会自动导入这些模块,而是作为向像 qmllint 这样的工具提供提示。版本可以与 IMPORTS 一样指定。此处列出的每个模块都将被添加到生成的 qmldir 文件中的 optional import 条目。

DEFAULT_IMPORTS 指定可选导入中的默认入口,这些入口应由工具加载。对于模块中每一组 OPTIONAL_IMPORTS 应指定一个条目。由于可选导入仅在运行时解析,因此工具(如 qmllint)通常无法知道哪个可选导入需要解析。为此,您可以指定一个可选导入作为默认导入;如此一来,工具会自动选择它。如果有一个可选导入在运行时使用,而没有其他任何配置,那么这是一个理想的默认导入候选者。

DEPENDENCIES 提供了一个依赖于此模块的其他 QML 模块的列表,但这些模块并非必然导入。这通常用于只在 C++ 级别存在的依赖项,例如,一个模块将一个注册到 QML 中的类(该类是另一个模块中定义的类的子类)注册作为模块。

例如,如果希望像下面这样子类化 QQuickItem

class MyItem: public QQuickItem { ... };

那么必须保证包含 QQuickItem 的模块(称为 Quick)以 DEPENDENCIES 选项的形式声明为依赖项。如果不这样做,使用 qmltc 进行类型编译或在将绑定和函数编译到 C++ 时使用 qmlcachegen 可能会导致错误。

注意:如果模块已通过 IMPORTS 选项导入,则无需在 DEPENDENCIES 中添加该模块。建议的方法是使用更轻量级的 DEPENDENCIES 替代 IMPORTS

必须与模块名称一起指定依赖项的模块版本,其格式与 IMPORTSOPTIONAL_IMPORTS 中使用的格式相同。所列出的每个模块将作为 depends 条目添加到生成的 qmldir 文件中。

可以使用 IMPORT_PATH 向搜索路径添加其他依赖于此模块的 QML 模块的位置。这些其他模块必须在其各自的目标路径下具有 `qmldir` 文件,该路径位于其中一个搜索路径下。

如果支持目标是一个静态库并且该静态库将安装,则应提供 OUTPUT_TARGETS,以便提供变量列表,这些变量也需要安装。这些附加目标由 qt_add_qml_module() 内部生成,并作为支持目标链接需求的一部分进行引用,以确保资源正确设置和加载。

目标和插件目标

PLUGIN_TARGET 指定了与 QML 模块关联的插件目标。如果 PLUGIN_TARGET 与支持目标相同,则将不会有单独的支持目标。如果未指定 PLUGIN_TARGET,则默认值为 target,后跟 `plugin`。例如,名为 mymodule 的支持目标会导致默认插件名为 mymoduleplugin。插件目标名称将用于填充生成的 qmldir 文件中的 plugin 行。因此,您不应该尝试通过设置目标属性(如 OUTPUT_NAME 或其相关属性)来更改插件输出名称。

后备目标 target 和插件目标(如果不同)将由命令创建,除非它们已经存在。项目通常应该让命令创建它们,以便它们以适当的目标类型创建。如果后备 target 是一个静态库,则插件也将作为静态库创建。如果后备 target 是一个共享库,则插件将作为模块库创建。如果传递了现有 target 并且它是一个可执行目标,则不会创建插件。如果您打算始终直接链接到后备目标且不需要插件,则可以通过添加 NO_PLUGIN 选项来禁用它。指定 NO_PLUGINPLUGIN_TARGET 两个选项是错误的。

在某些情况下,项目可能希望将插件目标的创建延迟到调用之后。可以给出 NO_CREATE_PLUGIN_TARGET 选项。项目在创建插件目标后应调用 qt_add_qml_plugin()。当给出 NO_CREATE_PLUGIN_TARGET 时,必须提供 PLUGIN_TARGET 以明确指定插件目标。

默认情况下,qt_add_qml_module() 将自动生成一个实现由 CLASS_NAME 参数命名的插件类的 .cpp 文件。生成的 .cpp 文件将被自动添加到插件目标中作为编译的源文件。如果项目想要提供自己的插件类实现,则应给出 NO_GENERATE_PLUGIN_SOURCE 选项。如果没有提供 CLASS_NAME,则默认为将点替换为下划线的 URI,然后附加 Plugin。除非 QML 模块没有插件,否则类名将作为生成的 qmldir 文件中的 classname 行记录。您需要将任何包含自定义插件代码的 C++ 文件添加到插件目标中。由于插件可能包含超出简单加载后备库的功能,因此您可能还想要添加 NO_PLUGIN_OPTIONAL。否则,如果 QML 引擎检测到后备库已经链接,则可能会跳过加载插件。

如果给出 NO_PLUGIN 关键字,则不会构建任何插件。因此,该关键字与所有自定义插件目标选项不兼容,尤其是 NO_GENERATE_PLUGIN_SOURCENO_PLUGIN_OPTIONALPLUGIN_TARGETNO_CREATE_PLUGIN_TARGETCLASS_NAME。如果您不为您的模块提供插件,它只有在后备库被链接到可执行文件的情况下才能完全使用。通常很难保证链接器保留对它认为未使用的库的链接。

如果给出 NO_PLUGIN_OPTIONAL 关键字,则插件将被记录在生成的 qmldir 文件中为非必需。如果一个 QML 模块的所有功能都在其后备目标中实现,且插件目标是单独的,则插件可以是可选的,这是默认和推荐的结构。自动生成的插件源文件满足此要求。如果一个项目为其插件提供了自己的 .cpp 实现,那么通常意味着需要也提供 NO_PLUGIN_OPTIONAL 关键字,因为插件很可能包含 QML 模块需要的功能。

自动类型注册

对于由AUTOMOC处理的背县目标的C++源文件,类型注册将自动执行。这将在输出目录中生成typeinfo文件,文件名是target名称,后跟.qmltypes。如果需要,可以使用TYPEINFO选项更改文件名,但通常不需要这样做。此文件名还记录为在生成的qmldir文件中的typeinfo条目。可以通过使用NO_GENERATE_QMLTYPES选项禁用自动类型注册,在这种情况下不会生成typeinfo文件,但项目仍然需要生成typeinfo文件并将其放在生成的qmldir文件相同的目录中。

OUTPUT_DIRECTORY指定插件库、qmldir和typeinfo文件生成的位置。当此关键字未指定时,默认值将是目标路径(由URI形成)附加到QT_QML_OUTPUT_DIRECTORY变量值。如果没有定义该变量,默认值取决于支持目标类型。对于可执行文件,值将是目标路径附加到${CMAKE_CURRENT_BINARY_DIR},而对于其他目标,它将是仅有的${CMAKE_CURRENT_BINARY_DIR}。当源树的结构与QML模块目标路径结构相匹配(这强烈推荐)时,QT_QML_OUTPUT_DIRECTORY通常不需要。为了匹配目标路径结构,你必须将你的目录精确地命名为你的模块URI段。例如,如果你的模块URI是MyUpperCaseThing.mylowercasething,你需要将其放在名为MyUpperCaseThing/mylowercasething/的目录中。

指定OUTPUT_DIRECTORY关键字的必要性应该很少,但如果是用来使用的,调用者可能还需要将到IMPORT_PATH的添加以确保lintingcached compilation of qml sources、automatic importing of plugins in static builds、以及deploying imported QML modules for non-static builds都能正确工作。

Qt Quick Designer兼容性

如果QML模块支持Qt Quick Designer,应提供DESIGNER_SUPPORTED。当存在时,生成的qmldir文件将包含一个designersupported行。有关此如何影响Qt Quick Designer处理插件的方式,请参阅Module Definition qmldir Files

使模块版本保持同步

FOLLOW_FOREIGN_VERSIONING 关键词与您自己的 C++ 定义的 QML 类型的基本类型相关,这些类型存在于不同的 QML 模块中。通常,您模块的版本方案与提供基本类型的模块的版本方案不匹配。因此,默认情况下,您的模块的所有导入都将提供基本类型的所有版本。如果提供了 FOLLOW_FOREIGN_VERSIONING,则将尊重附加到基本类型及其属性上的版本信息。因此,import MyModule 2.8 只会提供来自 MyModule 外部任何基本类型的版本直到 2.8 版本的已版本化属性。如果在您所依赖的类型所在的模块中,您希望保持与模块的版本同步,那么这非常有用。在这种情况下,您可能希望您的自定义类型不暴露来自模块基本类型版本的属性,该版本高于被导入版本。

生成代码的 C++ 命名空间

如果有 NAMESPACE 关键字指定了命名空间,那么插件和注册代码将生成在此命名空间名称的 C++ 命名空间中。

qmlimportscannerNO_IMPORT_SCAN

对于静态 Qt 构建,qmlimportscanner 在配置时运行以扫描 QML 模块的 .qml 文件并确定它使用的 QML 导入(参见 qt_import_qml_plugins())。对于非静态 Qt 构建,如果目标是可执行文件,则在构建时执行类似的扫描,以提供部署脚本所需的信息(参见 qt_deploy_qml_imports())。两种扫描都可以通过提供 NO_IMPORT_SCAN 选项来禁用。这样做的含义是,项目承担确保所有必需的插件都被实例化和链接以便静态构建的责任。对于非静态构建,项目必须手动确定和部署可执行目标所使用的所有 QML 模块。

qmltc 的参数

ENABLE_TYPE_COMPILER 可以使用 qmltc.qml 文件编译成 C++ 源代码。具有属性 QT_QML_SKIP_TYPE_COMPILER 的文件不会编译成 C++。

TYPE_COMPILER Namespace 参数允许您覆盖 qmltc 生成代码的命名空间。默认情况下,生成代码的命名空间遵循模块层次结构,如 URI 所示,例如,对于 URI 为 MyModule 的模块,为 MyModule 或对于 URI com.example.MyModule 的 URI,为 com::example::Module。通过指定 TYPE_COMPILER Namespace 选项,生成的代码可以放置在自定义命名空间中,其中不同的子命名空间之间用 "::" 分隔,例如,对于在 MyNamespace 内的 MySubnamespace 命名空间,为 "MyNamespace::MySubnamespace"。除了 "::" 之外,C++ 命名空间命名规则适用。

qmltc 生成的类应该从 qml 库导出时,应使用 QMLTC_QMLTC_EXPORT_DIRECTIVEQMLTC_EXPORT_FILE_NAME 结合使用。默认情况下,由 qmltc 生成的类不会从它们的库中导出。可以将导出宏的定义头文件指定为 QMLTC_EXPORT_FILE_NAME 的可选参数,同时应将导出宏的名称指定为 QMLTC_QMLTC_EXPORT_DIRECTIVE 的参数。如果没有额外的包含要求或想要包含,例如当基类的导出宏头文件已经是间接包含时,则可以省略 QMLTC_EXPORT_FILE_NAME 选项。

© 2024 Qt公司有限公司。本文档中包含的文档贡献归各自所有者所有。本提供的文档是根据自由软件开发基金会发布的、在GNU自由文档许可版本1.3的条款许可的。Qt及其相关标志是芬兰及全球其他国家的Qt公司有限公司的商标。所有其他商标均为各自所有者的财产。