Qt 的资源系统用于存储应用程序的可执行二进制文件,它采用平台无关的机制。当你的程序总须要这样的一系列文件(图标、翻译文件等)而且不想冒丢失某些文件的风险时,这就显得十分有用。数组
资源系统基于 qmake、rcc(Qt 资源编译器) 和 QFile 之间的紧密合做。markdown
与程序相关的资源在被指定在一个 .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()。