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.h
和foo.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被构建为共享库,则将其创建为共享库,否则创建为静态库。可以使用STATIC
或SHARED
选项显式覆盖此选择。
每个QML模块都必须定义一个URI
。它应该指定为点分URI表示法,例如QtQuick.Layouts
。每个段必须是有效的ECMAScript标识符名称。这意味着,例如,段不能以数字开头,并且不能包含-(减号)字符。由于URI
将被转换为目录名,因此应将其限制为拉丁字母的字母数字字符、下划线和点。其他QML模块可以使用此名称在导入语句中导入模块。使用URI
在生成的qmldir文件的module
行中使用。将使用URI
通过将点替换为正斜杠来形成目标路径。
有关模块URI的更深入讨论,请参阅已识别模块。
版本
QML模块还可以定义以Major.Minor
形式的VERSION
,其中Major
和Minor
都必须是整数。还可以附加一个可选的.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
。
必须与模块名称一起指定依赖项的模块版本,其格式与 IMPORTS
和 OPTIONAL_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_PLUGIN
和 PLUGIN_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_SOURCE、NO_PLUGIN_OPTIONAL、PLUGIN_TARGET、NO_CREATE_PLUGIN_TARGET 和 CLASS_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的添加以确保linting、cached 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++ 命名空间中。
qmlimportscanner
和 NO_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_DIRECTIVE
与 QMLTC_EXPORT_FILE_NAME
结合使用。默认情况下,由 qmltc 生成的类不会从它们的库中导出。可以将导出宏的定义头文件指定为 QMLTC_EXPORT_FILE_NAME
的可选参数,同时应将导出宏的名称指定为 QMLTC_QMLTC_EXPORT_DIRECTIVE
的参数。如果没有额外的包含要求或想要包含,例如当基类的导出宏头文件已经是间接包含时,则可以省略 QMLTC_EXPORT_FILE_NAME
选项。
© 2024 Qt公司有限公司。本文档中包含的文档贡献归各自所有者所有。本提供的文档是根据自由软件开发基金会发布的、在GNU自由文档许可版本1.3的条款许可的。Qt及其相关标志是芬兰及全球其他国家的Qt公司有限公司的商标。所有其他商标均为各自所有者的财产。