Qt之资源系统

简述

Qt 的资源系统用于存储应用程序的可执行二进制文件,它采用平台无关的机制。当你的程序总须要这样的一系列文件(图标、翻译文件等)而且不想冒丢失某些文件的风险时,这就显得十分有用。数组

资源系统基于 qmake、rcc(Qt 资源编译器) 和 QFile 之间的紧密合做。markdown

资源集合文件(.qrc)

与程序相关的资源在被指定在一个 .qrc 文件中,其基于 XML 的文件格式列出了磁盘上的文件,能够为它们指定一个应用程序访问资源时必须使用的资源名称。app

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

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <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>

.qrc 文件中列出的资源文件是程序代码树中的一部分。指定的路径相对于 .qrc 文件所在目录。注意:列出的资源文件必须位于 .qrc 文件所在目录或其子目录。ui

资源数据能够编译成二进制,进而在程序代码中当即访问;或者建立一个二进制资源,在晚些时候用资源系统来注册程序代码。this

默认状况下,程序可使用与代码树中相同的名字访问资源,须要带有 “:/” 前缀,或者有qrc scheme的URL。spa

例如: :/images/cut.png 或者URL qrc:///images/cut.png 均可以访问在程序代码树中位置为 images/cut.png 的 cut.png 文件。用文件标签的别名属性能够改变访问名称:操作系统

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

以后,在程序中就可使用 :/cut-img.png 访问此文件了。还可使用 qresource 标签的前缀属性为 .qrc 文件中列出的全部文件指定路径前缀:插件

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

这种状况下,就可使用 :/myresources/cut-img.png 访问该文件了。命令行

有些资源可能须要随着用户本地的配置而改变,例如:翻译文件、图标,能够经过为 qresource 标签添加一个 lang 属性,并指定一个适当的本地字符串来完成。例如:

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

若是用户的语言是法语(即:QLocale::system().name() 返回“fr_FR”),:/cut.jpg 就变成了对 cut_fr.jpg 文件的引用。若是是其它语言,仍然使用 cut.jpg 。

使用语言字符串的格式的说明能够参考 QLocale 文档。

外部二进制资源

要建立外部二进制资源,必须经过传递 -binary 给 rcc 来建立资源数据(一般使用 .rcc 扩展名),一旦二进制资源被建立,就可使用 QResource API 注册该资源。

例如, .qrc 文件中指定的一系列资源数据能够用下面的方式编译:

rcc -binary myresource.qrc -o myresource.rcc

在程序里,须要用如下代码注册该资源:

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

内编译资源

要把一个资源编译到二进制文件中, 必须在 .pro 中明确指定.qrc 文件,以便于 qmake 能够正确处理。例如:

RESOURCES = application.qrc

qmake 会产生 make 规则来生成一个连接到程序中的名为 qrc_application.cpp 的文件。这个文件以静态的 C++ 压缩二进制数组包含了全部图片和其它资源的数据。当 qrc_application.cpp 自己或者是其引用的资源文件发生改变后,该文件都会被自动从新生成。若是你不使用 .pro 文件,那么能够手工调用 rcc 或者为 build 系统添加 build 规则。

这里写图片描述

目前,Qt 老是把资源数据存储在可执行文件中,甚至是在 Windows、Mac OS X 和 iOS 这些原生支持资源机制的操做系统中。在未来的 Qt release 版本中可能会改变。

压缩

默认状况下,资源是被压缩的(ZIP 格式),也能够关闭压缩。若是你的资源已经包含了一个压缩格式(例如: .png 文件),这可能会比较有用。能够经过命令行传递 -no-compress 来指定:

rcc -no-compress myresources.qrc

rcc 也在压缩上给你提供了一些控制,当压缩文件时,能够指定压缩级别和阈值水平时,例如:

rcc -compress 2 -threshold 3 myresources.qrc

在程序中使用资源

在程序中,资源路径在大多数状况能够代替通常的文件系统路径。特别是,能够用资源路径取代文件名传递给 QIcon、 QImage ,或者 QPixmap 的构造函数:

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

能够参考 Application 示例,了解更多关于应用程序使用 Qt 资源系统来存储图标的内容。

在内存中,资源由一个资源对象树来表示。此树在程序启动时被自动生成,并被 QFile 用来解析路径到资源。你可使用带有 “:/” 前缀的 QDir 从根目录开始遍历这棵树。

Qt 资源系统支持搜索路径列表。若是你用 : 代替 :/ 做为前缀,则会使用搜索路径列表来搜索资源。程序启动时搜索路径列表为空,能够用 QDir::addSearchPath() 为其添加路径。

若是有资源位于静态库中,须要用不带有后缀的 .qrc 文件名为参数调用 Q_INIT_RESOURCE() 来强制初始化资源系统。例如:

在库中使用资源

若是有资源位于一个库中,须要用不带有后缀的 .qrc 文件名为参数调用 Q_INIT_RESOURCE() 来强制初始化资源系统。例如:

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

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

在静态连接的状况下,这确保了资源被连接到最终应用程序的二进制文件中。应该把初始化代码接近库中资源被使用的地方,这样以来,若是库的客户端用库的特性,它们只会连接进资源。

注意:因为 rcc 初始化资源生成在全局命名空间中声明,你也须要在任何命名空间以外的地方调用 Q_INIT_RESOURCE()。

若是库内部包含未使用的资源,可是暴漏给库的客户端,初始化须要发生在应用程序代码中,例如:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Q_INIT_RESOURCE(graphlib);

    QFile file(":/graph.png");
    ...
    return app.exec();
}

和以前同样,这确保在静态连接的状况下,资源被连接到最终应用程序的二进制文件中,也触发加载动态链,例如:插件。

一样的,你必须明确地卸载一个显式设置的资源(由于一个插件被卸载或资源再也不有效),你能够强制删除资源经过调用 Q_CLEANUP_RESOURCE() 与上面相同的基本名称。

注意:当资源被构建为应用程序的一部分时,没有必要使用 Q_INIT_RESOURCE() 和Q_CLEANUP_RESOURCE()。

相关文章
相关标签/搜索