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 ...
随机推荐
- (1)创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)、减速(车速自减)、修改车牌号,查询车的载重量。 编写两个构造方法:一个没有形参,在方法中将车牌号设置“XX1234”,速 度设置为100,载重量设置为100;另一个能为对象的所有属性赋值; (2)创建主类: 在主类中创建两个机动车对象。
package a; public class Jidongche { private String chepaihao; private int chesu; private double zaiz ...
- 瞧,这就是UE4 C++
1.虚幻中的类前缀你会见到U,A,F,以下就是很好的罗列其中的意义 U: UObject继承过来的,例如UTexture A: AActor继承过来的,例如AGameMode F: 其他的类和结构,例 ...
- Windows下通过bat脚本实现自动上传文件到ftp服务器
@Echo Off Echo open ip_address [port] >ftp.up Echo [username]>>ftp.up Echo [password]>&g ...
- SQL疑难杂症【3】链接服务器提示"无法启动分布式事物"
今天接到用户反馈,应用系统出现异常,无法正常使用,于是用Profiler跟踪了一下语句,发现执行的存储过程中调用了链接服务器,做了一些跨服务器操作数据的动作,刚好就是这个链接服务器出错了,错误截图如下 ...
- ZOJ 3819 Average Score(平均分)
Description 题目描述 Bob is a freshman in Marjar University. He is clever and diligent. However, he is n ...
- python_way ,day1 编译安装python3、基础及流程控制
本节内容: 1,Python介绍发展史 2,安装 3,Hello World 4,程序 5,变量,字符编码 6,用户输入 7,模块初识 一.python介绍 python的创始人为吉多·范罗苏姆(Gu ...
- git学习笔记10-新开发的功能不想要了-强行删除分支
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支. 现在,你终于接 ...
- Maven生命周期(插件)
maven拥有三套相互独立的生命周期,它们分别是clean,default和site.clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site 生命周期的目的是建立项目站 ...
- 触发器创建及Navicat中使用
mysql中的触发器(trigger)使用 Trigger: 示例: mysql,)); Query OK, rows affected (0.03 sec) mysql> CREATE TRI ...
- bootstrap学习笔记<六>(表单二之按钮)
按钮(补充) (ps:居中元素可以使用<center></center>标签) 块级按钮(ps:按钮占一整行) <button class="btn btn-p ...