Qt之资源系统
简述
Qt 的资源系统用于存储应用程序的可执行二进制文件,它采用平台无关的机制。当你的程序总需要这样的一系列文件(图标、翻译文件等)并且不想冒丢失某些文件的风险时,这就显得十分有用。
资源系统基于 qmake、rcc(Qt 资源编译器) 和 QFile 之间的紧密合作。
资源集合文件(.qrc)
与程序相关的资源在被指定在一个 .qrc 文件中,其基于 XML 的文件格式列出了磁盘上的文件,可以为它们指定一个应用程序访问资源时必须使用的资源名称。
下面是一个 .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 文件所在目录或其子目录。
资源数据可以编译成二进制,进而在程序代码中立即访问;或者创建一个二进制资源,在晚些时候用资源系统来注册程序代码。
默认情况下,程序可以使用与代码树中相同的名字访问资源,需要带有 “:/” 前缀,或者有qrc scheme的URL。
例如: :/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()。
更多参考
- The Qt Resource System - Qt 助手
Qt之资源系统的更多相关文章
- Qt:Qt资源系统
学习自 Qt 资源系统(Qt Resource System) - 知乎 1.什么是Qt 资源系统 Qt资源系统是一种将图片.数据存储于二进制文件中的一套系统.这些图片.数据会被我们的程序使用,它们称 ...
- QT中自定义系统托盘的实现—c++语言为例
将要介绍的是:QT中自定义系统托盘(systemtray)的一个Demo,希望能帮需要的读者快速上手. 前提假设是诸位已经知道QT中的signals .slot以及资源文件,所以关于这些不会再累述. ...
- 学习Qt的资源-网站、论坛、博客等
来自<零基础学Qt 4编程>一书的附录 附录C Qt资源 C.1 Qt 官方资源 全球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程 ...
- 【转载】分享一些Qt学习资源,欢迎下载
资源来源:http://bbs.csdn.net/topics/390358737 经过我一翻整理,把一些我收集到的Qt学习资源分享给大家,主要适合新手,老鸟可以直接忽略我.要说明一下,很多资源都是在 ...
- ylbtech-dbs:ylbtech-3,BarCode(条码资源系统)
ylbtech-dbs:ylbtech-3,BarCode(条码资源系统) -- =============================================-- 条码资源系统-- YU ...
- QT的Paint 系统
下面对于QT的绘制系统做一个简要说明, 这个系统主要由三部分组成, QPainter, QPaintDevice, QPaintEngine. QPainter 是一个绘制接口类,提供绘制各种面向用 ...
- QT下资源使用和资源占用…(可以动态加载资源文件,这样不占内存)
原文地址:关于QT下资源使用和资源占用内存过多的问题作者:技术成就梦想 最近研究了一下如何从外部动态调用图片的问题,从而研究了图片资源的使用方法.网上最常见的帖子是这个,感觉总结的还不错. h ...
- 关于QT下资源使用和资源占用…
原文地址:关于QT下资源使用和资源占用内存过多的问题作者:技术成就梦想 最近研究了一下如何从外部动态调用图片的问题,从而研究了图片资源的使用方法.网上最常见的帖子是这个,感觉总结的还不错. h ...
- 解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
概述查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别. 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起. Q_INVOKABLE与QMe ...
随机推荐
- UVA 10453 十七 Make Palindrome
Make Palindrome Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit St ...
- MySQL(四) —— 操作数据表中的记录
插入记录 INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),... //法二: ...
- [HDOJ5877]Weak Pair(DFS,线段树,离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意:给一棵树和各点的权值a,求点对(u,v)个数,满足:1.u是v的祖先,2.a(u)*a(v ...
- 用Spring MVC开发简单的Web应用
这个例子是来自于Gary Mak等人写的Spring攻略(第二版)第八章Spring @MVC中的一个例子,在此以学习为目的进行记录. 问题:想用Spring MVC开发一个简单的Web应用, 学习这 ...
- windows c dll的创建与调用
DLL代码: // TestDynamic.cpp: implementation of the TestDynamic class. // ///////////////////////////// ...
- 随机内容生成(random模块)
摘抄于: 低调的python小子 当梦想照进现实 幸福近在咫尺 [jpg]http://ip.ipwind.cn/msn.png[/jpg] Python中的random模块用于生成随机数.下面介绍 ...
- HTML笔记(一)
HTML注释格式如下: <!-- 这里是注释 --> HTML中的标题(heading)通过h1~h6来定义. 文本格式化标签: 标签 描述 <b> 定义粗体文本. <b ...
- PhpStorm的注册码、Key
下面是PhpStorm的注册码.Key,其license由用户名和License值组成. User name: EMBRACE License key: ===== LICENSE BEGIN === ...
- 动态CSS--less
忙了很久终于有时间来写点东西了,不知道大家有没有发现,我们在写CSS的时候总是在重复很多代码,一个相同的属性值往往要重复N次,以前我就经常想有没有什么办法能让我们不用一直重复的font-size啊co ...
- SQL.变量、运算符、if、while
变量: SQL语言也跟其他编程语言一样,拥有变量.分支.循环等控制语句. 在SQL语言里面把变量分为局部变量和全局变量,全局变量又称系统变量. 局部变量: 使用declare关键字给变量声明,语法非常 ...