Qt 资源系统

Qt 资源系统是一种独立于平台的机制,用于在应用程序中传输资源文件。如果您的应用程序总是需要一组特定的文件(如图标、翻译文件、图像),而您又不想使用特定于系统的方法来打包和定位这些资源,那么就可以使用它。

最常见的情况是,将资源文件嵌入到应用程序可执行文件中,或嵌入到由应用程序可执行文件加载的库和插件中。另外,资源文件也可以存储在外部资源文件中。

资源系统基于 Qt 的rcc资源编译器、构建系统和 Qt 运行时 API 之间的紧密合作。

注意: 目前,Qt 资源系统没有使用任何特定于系统的功能来处理资源,如 Windows、macOS 和 iOS 上的功能。这可能会在未来的 Qt 版本中有所改变。

QtResource Compiler (rcc)

Resource Compiler (rcc)命令行工具读取资源文件并生成 C++ 或 Python 源文件或.rcc 文件。

文件列表和相关元数据以Qt 资源收集文件的形式传递给rcc

默认情况下,rcc 将生成 C++ 源代码,然后编译为可执行文件或库的一部分。-g python 选项会生成 Python 源代码。-binary 选项会生成二进制归档文件,按惯例保存在.rcc 文件中,可在运行时加载。

注意: 虽然可以通过命令行运行rcc ,但最好还是交由构建系统来完成。另请参阅下文有关qmakeCMake的章节。

Qt 资源集合文件 (.qrc)

.qrc 文件是一个 XML 文档,它列举了要作为运行时资源包含的本地文件。它是rcc 的输入文件。

下面是一个.qrc 文件示例:

<RCC>
    <qresource prefix="/">
        <file>images/copy.png</file>
        <file>images/cut.png</file>
        <file>images/new.png</file>
        <file>images/open.png</file>
        <file>images/paste.png</file>
        <file>images/save.png</file>
    </qresource>
</RCC>

XML 中的每个<file> 元素都标识了应用程序源代码树中的一个文件。路径是相对于包含.qrc 文件的目录解析的。

默认情况下,该路径也用于在运行时标识文件内容。也就是说,文件titlebarLeft.png 在资源系统中将显示为:/res/titlebarLeft.pngqrc:/res/titlebarLeft.png 。要覆盖这一默认运行时名称,请参阅前缀别名

Qt Creator, Qt Design StudioQt Widgets DesignerQt Visual Studio Tools允许您通过便捷的用户界面创建、检查和编辑.qrc 文件。除Qt Widgets Designer 外,它们还为使用 Qt 资源系统的项目提供向导。

构建系统集成

使用rcc 处理资源文件通常是在构建应用程序时进行的。包括CMakeqmake 在内的多个构建工具都为此提供了专门支持。

CMake

如果启用了CMAKE_AUTORCC ,就可以直接将.qrc 文件作为源代码添加到可执行文件或库中。然后,引用的资源文件就会嵌入到二进制文件中:

set(CMAKE_AUTORCC ON)

qt_add_executable(my_app
    application.qrc
    main.cpp
)

有关AUTORCC 的更多详情,请参阅CMake 的AUTORCC文档

AUTORCC 的另一个替代方法是使用 Qt6Core 的 CMake 函数qt_add_resources,它对资源的创建提供了更多控制。例如,它允许您直接在项目文件中指定资源的内容,而无需先编写.qrc 文件:

qt_add_resources(my_app "app_images"
    PREFIX "/"
    FILES
        images/copy.png
        images/cut.png
        images/new.png
        images/open.png
        images/paste.png
        images/save.png
)

最后,qt_add_qml_module可以将Qt Quick 资源嵌入应用程序的资源系统。该函数定义在Qt6 CMake 包的Qml 组件中。

qmake

qmake支持使用RESOURCES变量来处理资源。如果在变量中添加.qrc 文件路径,列出的资源文件就会嵌入到生成的库或可执行文件中:

RESOURCES = application.qrc

这将创建一个由多个.png 文件组成的资源,这些文件的地址如下:":/res/titlebarLeft.png".

如果要嵌入到资源中的文件目录布局与应用程序的预期不符,可以指定resources.basebase 是一个路径前缀,表示文件别名的根点。在上面的示例中,如果resources.base 被设置为"res" ,那么titlebarLeft.png 可被寻址为":/titlebarLeft.png"

运行时 API

处理迭代和读取文件的 Qt API 内置了对 Qt 资源系统的支持。您可以向QFileQDir 以及QIconQImageQPixmap 构造函数传递资源路径,而不是本地文件路径:

    cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);

: 前缀明确表示应从 Qt 资源系统加载"/images/cut.png"。

您也可以通过QUrl 引用 Qt 资源系统。此时请使用qrc 方案:

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/myapp/main.qml"));

高级主题

前缀

.qrc 文件可以设置一个前缀,将其添加到<file> 元素中给出的每个本地文件名中,以获得该文件在资源系统中的名称。

使用前缀可以构建资源结构,避免通过不同库或插件中的不同.qrc 文件添加的资源文件之间发生冲突。

注意: /qt/qt-project.org 前缀是为 Qt 中的文档用例保留的。例如,qt.conf文件可在:/qt/etc/qt.confqrc:/qt/etc/qt.conf 中查找。

别名

.qrc 文件通过设置alias 属性来实现这一点:

<file alias="cut-img.png">images/cut.png</file>

该文件来自应用程序,因此只能以:/cut-img.pngqrc:/cut-img.png 的形式访问。

丢弃文件内容

有时,您想在资源文件系统中添加文件节点,但实际上并不想添加文件内容。.qrc 文件允许这样做,方法是将empty 属性设置为true

<file empty="true">Button.qml</file>

这样生成的文件仍可从应用程序中访问,但其内容是空的。

这对于从应用程序二进制文件中剥离 QML 源代码很有用。

注意: 如果从二进制文件中省略 QML 源代码,QML 引擎就必须依赖qmlcachegenqmlsc 创建的编译单元。这些单元与它们构建时使用的特定 Qt 版本相关。如果更改了应用程序使用的 Qt 版本,它们就无法再被加载。

语言选择器

有些资源(如翻译文件或图标)需要根据用户的本地语言进行更改。资源收集文件通过qresource 标签的lang 属性来支持这一点,该属性指定了一个合适的语言字符串。例如

<qresource>
    <file>cut.jpg</file>
</qresource>
<qresource lang="fr">
    <file alias="cut.jpg">cut_fr.jpg</file>
</qresource>

如果用户的 locale 是法语(即QLocale::system().language() 是法语),:/cut.jpgqrc:/cut.jpg 将成为cut_fr.jpg 图像的引用。对于其他语言,则使用cut.jpg

有关本地字符串的格式说明,请参阅QLocale 文档。

请参阅QFileSelector ,了解选择特定本地资源的其他机制。

嵌入大型文件

默认情况下,rcc 会以 C++ 数组的形式将资源文件嵌入可执行文件。这可能会造成问题,尤其是对于大型资源。

如果编译器耗时过长,甚至因内存溢出而导致编译失败,您可以选择一种特殊模式,将资源嵌入作为两步程序的一部分。C++ 编译器只在目标可执行文件或库中为资源预留足够的空间。资源文件内容和元数据的实际嵌入则在编译和链接阶段之后,通过另一个 rcc 调用完成。

对于 CMake,你需要使用qt_add_big_resources函数。

外部资源文件

除了将资源文件嵌入二进制文件外,另一种方法是将它们存储在单独的.rcc 文件中。rcc 允许使用-binary 选项来实现这一点。这样的.rcc 文件必须在运行时用QResource 加载。

例如,在.qrc 文件中指定的一组资源数据可以按以下方式编译:

rcc -binary myresource.qrc -o myresource.rcc

在应用程序中,该资源将通过如下代码注册:

QResource::registerResource("/path/to/myresource.rcc");

如果使用 CMake,可以使用qt_add_binary_resources函数来调度上述rcc 调用:

qt_add_binary_resources(resources application.qrc DESTINATION application.rcc)
add_dependencies(my_app resources)

Qt for Python 应用程序中的资源

资源集合文件通过资源编译器rcc 转换为 Python 模块:

rcc -g python mainwindow.qrc > mainwindow_rc.py

然后就可以在应用程序中导入该模块:

import mainwindow_rc.py

压缩

rcc 会尝试压缩内容,以优化最终二进制文件的磁盘空间使用。默认情况下,它会执行启发式检查,以确定压缩是否值得,如果不能充分压缩,就会以未压缩的方式存储内容。要控制阈值,可以使用 选项,该选项告诉 要以压缩形式存储文件,必须获得原始文件大小的百分比。-threshold rcc

rcc -threshold 25 myresources.qrc

默认值为 "70",表示压缩后的文件必须比原始文件小 70%(不超过原始文件大小的 30%)。

如果需要,也可以关闭压缩。如果您的资源已经包含压缩格式(如.png 文件),而您又不想在构建时花费 CPU 来确认文件是否可以压缩,那么关闭压缩可能会很有用。另一个原因是,如果磁盘使用不成问题,而应用程序希望在运行时将内容保留为干净的内存页面。为此,您可以提供-no-compress 命令行参数。

rcc -no-compress myresources.qrc

rcc 例如,您还可以控制压缩级别和压缩算法:

rcc -compress 2 -compress-algo zlib myresources.qrc

也可以在 .qrcfile 标签中使用compress,threshold 作为属性。要选择算法,请设置compression-algorithm 属性。

<qresource>
    <file compress="1" compression-algorithm="zstd">data.txt</file>
</qresource>

以上将选择压缩级别为 1 的zstd 算法。

rcc......支持以下压缩算法和压缩级别:

  • best:使用以下算法中最好的算法,压缩级别最高,以达到最大的压缩效果,但在编译过程中会占用大量 CPU 时间。在 XML 文件中,无论rcc 支持哪种算法,该值都可用于指示文件应采用最高压缩级别。
  • zstdZstandard:使用Zstandard库压缩内容。有效的压缩级别从 1 到 19 不等,1 表示压缩最少(占用 CPU 时间最少),19 表示压缩最多(占用 CPU 时间最多)。默认级别为 14。特殊值 0 会告诉zstd 库选择一个实现定义的默认值。
  • zlibzlib:使用zlib库压缩内容。有效的压缩级别从 1 到 9,1 表示压缩最少(占用最少 CPU 时间),9 表示压缩最多(占用最多 CPU 时间)。特殊值 0 表示 "不压缩",不应使用。默认值由执行情况决定,但通常是第 6 级。
  • none:无压缩。这与-no-compress 选项相同。

对 Zstandard 和 zlib 的支持都是可选的。如果在编译时未检测到指定的库,试图为该库传递-compress-algo 将导致错误。如果启用了zstd ,默认的压缩算法就是 ;如果没有启用,默认的压缩算法就是zlib

嵌入式资源的显式加载和卸载

嵌入 C++ 可执行文件或库代码中的资源会在内部全局变量的构造函数中自动注册到 Qt 资源系统中。由于全局变量是在 main() 运行前初始化的,因此当程序开始运行时,资源就可用了。

静态库中嵌入资源时,C++ 链接器可能会删除注册资源的静态变量。因此,如果在静态库中嵌入资源,就需要使用.qrc 文件的基名调用Q_INIT_RESOURCE() 来显式注册资源。例如

MyClass::MyClass() : BaseClass()
{
    Q_INIT_RESOURCE(resources);

    QFile file(":/myfile.dat");
    ...
}

您也可以从应用程序中显式删除已注册的资源,例如在卸载插件时。为此请使用Q_CLEANUP_RESOURCE() 。

注意:由于 rcc 生成的资源初始化程序是在全局命名空间中声明的,因此需要在任何命名空间之外调用Q_INIT_RESOURCE() 和Q_CLEANUP_RESOURCE() 。

© 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.