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_GENERATE_EXTRA_QMLDIRS]
    [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 Language Server.

说明

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

目标结构

QML 模块可以有几种不同的结构。以下是典型的安排:

独立的后备目标和插件目标

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

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

下例显示了一个 URI 为MyThings.Panels 的 QML 模块的合适源目录结构。对qt_add_qml_module() 的调用将在所示的CMakeLists.txt 文件中。

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

QML 模块有一个单独的插件目标。当应用程序尚未链接到后备目标时,它将在运行时动态加载模块。插件目标也是一个库,通常与模块的qmldir文件安装在同一目录下。

插件目标最好只包含插件类的简单实现。这样就可以在qmldir 文件中将插件指定为可选项。这样,其他目标就可以直接链接到支持目标,运行时就不需要插件,从而提高加载性能。默认情况下,定义最小插件类的 C++ 源文件将自动生成并添加到插件目标中。如果 QML 模块需要自定义插件类实现,则需要NO_GENERATE_PLUGIN_SOURCENO_PLUGIN_OPTIONAL 选项

如果未指定NO_PLUGINSTATIC QML 模块也会生成静态 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文件和 typeinfo 文件。这些文件的内容由该命令的各种参数以及添加到后备目标的源文件和.qml 文件决定。OUTPUT_DIRECTORY 参数决定qmldir 和 typeinfo 文件的写入位置。如果 QML 模块有插件,该插件也将在与qmldir 文件相同的目录下创建。

如果QTP0004策略设置为NEW ,则每多一个包含.qml 文件的目录,就会生成另一个qmldir 文件。这些额外的qmldir 文件只是通过prefer 指令重定向到模块的基本目录。这样,模块中的所有 QML 组件,无论存放在哪个目录,都能互相访问。

如果使用的是静态构建的 Qt,在 CMake configure 运行时,将扫描后备目标的.qml 文件,以确定模块使用的导入,并设置链接关系(可以给出NO_IMPORT_SCAN 关键字来禁用此功能)。当模块中添加或删除.qml 文件时,CMake 通常会自动重新运行,并重新扫描相关文件,因为CMakeLists.txt 文件已被修改。在开发过程中,现有的.qml 文件可能会添加或删除一个导入或一个类型。就其本身而言,这不会导致 CMake 自动重新运行,因此您应明确地重新运行 CMake 以强制重新生成qmldir 文件并更新任何链接关系。

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

项目应尽可能使用自动生成的 typeinfo 和qmldir 文件。它们更易于维护,而且不像手写文件那样容易出错。不过,在项目需要自己提供这些文件的情况下,可以禁用自动生成功能。NO_GENERATE_QMLDIR 选项禁用qmldir 自动生成功能,NO_GENERATE_QMLTYPES 选项禁用 typeinfo 和 C++ 类型注册自动生成功能。如果自动生成的 typeinfo 文件可以接受,但项目希望使用不同的文件名,可以使用TYPEINFO 选项覆盖默认文件名(但通常不需要)。

缓存已编译的 QML 源代码

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

每个文件的资源路径由其相对于当前源代码目录(CMAKE_CURRENT_SOURCE_DIR )的路径决定。该资源路径会被附加到RESOURCE_PREFIX和目标路径连接形成的前缀(但请参阅NO_RESOURCE_TARGET_PATH以了解例外情况)。

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

通常情况下,项目应将.qml 文件放在与资源中相对位置相同的位置。如果.qml 文件的相对目录与所需资源路径不同,则需要明确指定其在资源中的位置。为此,必须在添加.qml 文件之前设置QT_RESOURCE_ALIAS 源文件属性。例如

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

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

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 扩展,可以用它启用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 代码中的问题,有些会告诉你 C++ 代码生成器没有实现 QML 语言的某些功能。在这两种情况下,qmlcachegen 仍会为这些函数生成字节码。如果你只想看到 QML 代码中的问题,你应该使用 qmllint 和为它生成的目标。

检查 QML 源代码

如果通过QML_FILES 关键字或调用qt_target_qml_sources() 将任何.qml 文件添加到模块中,则会自动创建一个单独的检测目标。该目标的名称将是target 后的_qmllint 。为了方便起见,我们还提供了一个all_qmllint 目标,它依赖于所有单独的*_qmllint 目标。

.js 文件的命名约定

JavaScript 文件名如果是作为组件命名的,应以大写字母开头。

或者,也可以使用小写文件名,并将源文件属性QT_QML_SOURCE_TYPENAME设置为所需的类型名称。

单子

如果 QML 模块有.qml 文件提供单例类型,这些文件需要将其QT_QML_SINGLETON_TYPE 源文件属性设为TRUE ,以确保singleton 命令写入qmldir文件。除了包含pragma Singleton 语句的 QML 文件外,还必须这样做。源属性必须在创建单例所属模块之前设置。

有关如何设置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++ 文件被放置到targetBINARY_DIR 的一个专用.qmltc/<target>/ 子目录中。然后,这些文件会自动添加到目标源中,并与其他源文件一起编译为 Qt C++ 代码。

在处理 QML_FILES 时,要遵守以下源文件属性:

  • QT_QMLTC_FILE_BASENAMEQT_QMLTC_FILES:使用该源文件属性可指定一个非默认的 .h 和 .cpp 文件名,这对于解决文件名冲突等问题可能很有用(想象一下,你有 main.qml 正在被编译,但 main.h 已经存在,所以 #include "main.h" 可能无法实现你期望的功能)。QT_QMLTC_FILE_BASENAME 预计是一个文件名(不带扩展名),因此前面的任何目录都会被忽略。与默认行为不同,QT_QMLTC_FILE_BASENAME 不使用小写。
  • QT_QML_SKIP_TYPE_COMPILERQMLTC_FILE_BASENAME:使用此源文件属性可指定 QML 文件必须被 qmltc 忽略。

参数

所需参数

target 指定 QML 模块的后备目标名称。默认情况下,如果 Qt 是以共享库的形式构建的,则以共享库的形式创建,否则以静态库的形式创建。可使用STATICSHARED 选项明确覆盖这一选择。

每个 QML 模块都必须定义一个URI 。它应该用点号 URI 符号指定,如QtQuick.Layouts 。每个段都必须是格式良好的 ECMAScript 标识符名称。举例来说,这意味着各段不得以数字开头,也不得包含-(减号)字符。由于URI 将被翻译成目录名,因此应限制为拉丁字母、下划线和点的字母数字字符。其他 QML 模块可能会在导入语句中使用该名称来导入模块。URI 将用于生成的qmldir文件的module 行。URI 也用于用正斜杠代替点来构成目标路径

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

版本

QML 模块也可定义VERSION ,形式为Major.Minor ,其中MajorMinor 都必须是整数。可附加.Patch ,但会被忽略。在PAST_MAJOR_VERSIONS 关键字后,还可选择给出模块所提供类型的早期主要版本列表(见下文)。有关版本号的更多深入讨论,请参阅 "识别模块"、"注册过去的主要版本 "和 "保持模块版本同步"。

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

为模块添加源代码和资源

SOURCES 指定要添加到后援目标的非 QML 源列表。这只是为了方便起见,等同于使用 CMake 内置命令将源代码添加到后备目标。target_sources()

QML_FILES 列出模块的 、 和 文件。除非给出 选项,否则这些文件将自动.qml .js .mjs NO_CACHEGEN 编译成字节码并嵌入到后备目标中。即使指定了 ,未编译的文件也始终存储在后备目标的嵌入资源中。除非给出 选项,否则未编译文件也将NO_CACHEGEN NO_LINT qmllint 通过单独的自定义编译目标 处理。默认情况下,这些文件还将用于在生成的qmldir文件中填充类型信息。可以通过 选项禁用 文件的自动生成。通常应避免使用该选项,但如果项目需要提供自己的 文件,则可以使用该选项。自 Qt 6.8 起,启用NO_GENERATE_QMLDIR qmldir qmldir QTP0004时, 将为 QML 模块中的每个子目录创建额外的 文件,确保每个 QML 文件都能通过隐式导入(implicit import)导入自己的模块。通过 标志,可以关闭 QML 模块的这种行为。 意味着 。qt_add_qml_module qmldir NO_GENERATE_EXTRA_QMLDIRS NO_GENERATE_QMLDIR NO_GENERATE_EXTRA_QMLDIRS

注: 关于如何在调用qt_add_qml_module() 后添加 qmlfiles,请参阅qt_target_qml_sources()。例如,您可能希望根据 if 语句表达式有条件地添加文件,或者从子目录中添加文件,只有在满足特定条件时才会添加。此外,使用qt_target_qml_sources()添加的文件还可以指定是否应跳过这些文件,以便进行inting、字节码编译或生成qmldir 文件。

RESOURCES 列出模块需要的其他文件,如 QML 代码中引用的图片。这些文件将作为编译后的资源添加(请参阅RESOURCE_PREFIX,了解它们的基点)。如有需要,可通过设置 源属性来控制它们的相对位置,就像 文件一样(请参阅QT_RESOURCE_ALIAS .qml 缓存已编译的 QML 源)。

RESOURCE_PREFIX 的目的是封装项目的命名空间,通常对项目定义的所有 QML 模块都是一样的。

不过,最好还是设置QTP0001CMake 策略。它定义了一个默认的资源前缀,确保 QML 模块最终位于 QML 引擎的默认导入路径下。

如果您设置了RESOURCE_PREFIX ,您还应将它添加到 QML 引擎的导入路径中,以便找到 QML 模块。

如果启用了QTP0001(如通过qt_standard_project_setup(REQUIRES 6.5) ),默认值是"/qt/qml/" ,否则是"/"

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

注册过去的主要版本

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

声明模块依赖关系

IMPORTS 提供了该模块导入的其他 QML 模块的列表。这里列出的每个模块都将作为 条目添加到生成的import qmldir文件中。如果 QML 文件导入了该模块,它也会导入 下列出的所有模块。可选择在斜线后添加版本,如 。省略版本将导入现有的最大版本。也可以只指定主版本,如 。在这种情况下,将导入所给主版本中可用的最大次版本。最后, 可以以版本 ( ) 的形式给出。如果给出 ,则当前模块正在导入的版本将传播到要导入的模块。给定模块 中的条目 ,如果 QML 文件指定 ,则导入版本 的 。对于遵循共同版本方案的相关模块,应使用 。IMPORTS QtQuick/2.0 QtQuick/2 autoQtQuick/auto auto YourModule QtQuick/auto import YourModule 3.14 3.14 QtQuick auto

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

DEFAULT_IMPORTS 指定哪些可选导入项是工具应加载的默认项。应为模块中的每组 指定一个条目。由于可选导入只在运行时解析,qmllint 等工具一般无法知道哪些可选导入应被解析。为了解决这个问题,可以将其中一个可选导入指定为默认导入,这样工具就会选择它。如果有一个可选导入在运行时使用,无需任何进一步配置,那么它就是默认导入的理想候选。OPTIONAL_IMPORTS

DEPENDENCIES 提供该模块依赖的其他 QML 模块的列表,但不一定导入。它通常用于只存在于 C++ 层面的依赖关系,例如一个模块向 QML 注册了一个类,而这个类是另一个模块定义的子类。

例如,如果要对QQuickItem 进行如下子类化:

class MyItem: public QQuickItem { ... };

则必须确保包含QQuickItem 的模块(称为QtQuick )通过DEPENDENCIES 选项声明为依赖关系。否则可能会导致在使用qmltc进行类型编译或使用qmlcachegen 将绑定和函数编译为 C++ 时出现错误。

注意: 如果模块已通过IMPORTS 选项导入,则无需将模块添加到DEPENDENCIES 。建议使用更轻便的DEPENDENCIES 而不是IMPORTS

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

IMPORT_PATH 可用于添加搜索路径,以便找到该模块依赖的其他 QML 模块。其他模块的 文件必须位于其中一个搜索路径下面的目标路径下。qmldir

如果后备目标是一个静态库,且该静态库将被安装,OUTPUT_TARGETS ,以提供一个变量来存储同样需要安装的附加目标列表。这些附加目标由qt_add_qml_module() 内部生成,并由后备目标的链接要求引用,以确保正确设置和加载资源。

注意: 自 Qt 6.8 起,可以向 IMPORTS 和 DEPENDENCIES 传递目标名称。详情请参见QTP0005

目标和插件目标

PLUGIN_TARGET 指定与 QML 模块相关联的插件目标。 可以与后盾 相同,在这种情况下,将没有单独的后盾目标。如果没有给出 ,则默认为 ,并附加 。例如,名为 的后备目标默认插件名称为 。插件目标的名称将被用于填充生成的PLUGIN_TARGET target PLUGIN_TARGET target plugin mymodule mymodulepluginqmldir文件中的 行。因此,请不要试图通过设置目标属性(如 或任何相关属性)来更改插件的输出名称。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() 将自动生成一个.cpp 文件,该文件将实现由CLASS_NAME 参数命名的插件类。生成的.cpp 文件将自动添加到插件目标中,作为要编译的源文件。如果项目希望提供自己的插件类实现,则应提供NO_GENERATE_PLUGIN_SOURCE 选项。如果没有提供CLASS_NAME ,则默认为URI ,用下划线代替圆点,然后附加Plugin 。除非 QML 模块没有插件,否则类名将作为classname 行记录在生成的qmldir文件中。您需要将任何带有自定义插件代码的 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 选项更改该文件名,但通常没有必要这样做。文件名也会作为typeinfo 条目记录在生成的qmldir文件中。可以使用NO_GENERATE_QMLTYPES 选项禁用自动类型注册,在这种情况下不会生成 typeinfo 文件,但项目仍会生成 typeinfo 文件,并将其与生成的qmldir 文件放在同一目录下。

OUTPUT_DIRECTORY 指定插件库、 和 typeinfo 文件的生成位置。如果没有给出该关键字,默认值将是qmldir QT_QML_OUTPUT_DIRECTORY变量值附加的目标路径(由 形成)。如果没有定义该变量,默认值取决于后备目标的类型。对于可执行文件,其值将是附加到 的目标路径,而对于其他目标,则只是 。当源代码树的结构与 QML 模块目标路径的结构一致时(强烈推荐),通常不需要URI ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}QT_QML_OUTPUT_DIRECTORY。为了与目标路径的结构相匹配,您必须完全按照模块 URI 的段落来调用您的目录。例如,如果您的模块 URI 是 ,则需要将其放在名为 的目录中。MyUpperCaseThing.mylowercasething MyUpperCaseThing/mylowercasething/

需要指定OUTPUT_DIRECTORY 关键字的情况应该很少,但如果使用了,调用者很可能还需要添加到IMPORT_PATH中,以确保linting、qml 源的缓存编译、静态构建中插件的自动导入,以及为非静态构建部署导入的 QML 模块都能正常工作。

Qt Quick 设计器兼容性

DESIGNER_SUPPORTED 应在 QML 模块支持 Designer 时给出。如果存在,生成的 文件将包含 行。有关这对 Designer 处理插件方式的影响,请参阅Qt Quick qmldir designersupported Qt Quick 模块定义 qmldir 文件

保持模块版本同步

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 将 文件编译为 C++ 源代码。带有源代码属性 的文件不会编译为 C++。.qml QT_QML_SKIP_TYPE_COMPILER

TYPE_COMPILER_NAMESPACE 参数允许覆盖qmltc生成代码的命名空间。默认情况下,生成代码的命名空间遵循 URI 中描述的模块层次结构,例如,URI 为 的模块为 ,URI 为 的模块为 。通过指定 选项,可以将生成的代码放入自定义命名空间,不同的子命名空间之间用":: "隔开,例如,"MyNamespace::MySubnamespace "表示 MyNamespace 内部的命名空间 MySubnamespace。除":: "外,C++ 命名空间命名规则也适用。MyModule MyModule com.example.MyModule com::example::Module TYPE_COMPILER_NAMESPACE

QMLTC_QMLTC_EXPORT_DIRECTIVEqmltc生成的类需要从 qml 库导出时,应使用 。默认情况下,qmltc 生成的类不从其库中导出。定义当前库中导出宏的头文件可以作为 的可选参数,而导出宏的名称应作为 的参数。如果不需要或不希望额外包含,例如导出宏的头文件已经被基类间接包含,则可以不使用 选项。QMLTC_EXPORT_FILE_NAME QMLTC_EXPORT_FILE_NAME QMLTC_QMLTC_EXPORT_DIRECTIVE QMLTC_EXPORT_FILE_NAME

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.