Qt:资源系统

1060 篇文章 297 订阅

Qt Resource System是什么?

Qt资源系统是一种将图片、数据存储在二进制文件中的一套系统。

一般我们在程序中调用一张图片作为某个按钮的图标,如果替换成另一张同名的图片,那么程序运行时会加载新的图标。有这么一种情况,开发者不希望这些图标被修改或者图标文件丢了程序界面也就不能正常显示。
 

怎么办呢?我们可以把这些图片储存在可执行文件(如 QQ.exe 文件)中,即使删除了文件夹中的图标也不会影响界面图标的加载,因为图标数据已经以静态数据的方式保存在可执行文件中了。当然,代价就是编译出的可执行文件容量会增加。克服这个缺点的办法就是动态加载资源,见后文。
 

Qt资源系统是独立于平台的,因为无论是图片还是翻译文件等,都会被打包成二进制数据。你可以将这些二进制数据保存在可执行文件中,即“静态加载资源”;你也可以将这些二进制数据单独保存在一个文件中,即“动态加载资源”

 

qrc 文件 – 配置文件

qrc文件是基于xml格式的资源系统配置文件,该文件中指定了各种资源的信息。完整的将资源文件打包成二进制数据的流程是:写 qrc 文件 -> 用 rcc 编译 -> 二进制数据。

如何写 qrc 文件

有两种方式:

  • 用 Qt Creator 写。
  • 纯手工写。

这里之所以有个“纯手工写”是因为 Qt Creator 只支持一个文件一个文件的添加,假如我有几百个图标要添加到 qrc 文件中,岂不累死?遇到这种情况我一般的做法是在命令行中列出所有文件,复制粘贴到 Sublime 文本中,然后用多行添加其他相同的字符,如 <file>images/ 之类的。

纯手工写需要熟悉 qrc 文件的规则,还是很简单的。无非就是文件名、别名、前缀、语言环境这么几种。基本上用 Qt Creator 写好一个完整的文件后照猫画虎就可以自己手写了。所以本节重点介绍用 Qt Creator 写 qrc 文件。

 

  1. 在项目中添加 Qt Resource File,给资源文件起个名即可创建出一个空的 qrc 文件。此时文件中还没有资源信息,只有两行简单的标识符。
  2. 我们在工程目录下创建一个 pic 文件夹用于存放资源文件,比如这里存放一个 about.png 图片。
  3. 在QtCreator 中打开 qrc 的资源编辑器,第一步永远都是添加前缀,例如 /logo。然后才是添加图片。

可以看出来,刚开始的两行标识符没了,剩下的就是包含前缀的资源信息了

前缀、别名、语言环境

qrc 文件可以设置资源的前缀、别名和适用的语言环境,本质上就是分组而已。

这里重点说下语言环境。语言环境和前缀是一起设置的。有时候我们同一个图标可能因为国家原因做了不同的版本,Qt 可以自动根据本机语言环境选择性加载不同的图标。

什么意思呢?比如我有两个图标 about.png、about_fr.png,并且我把 about_fr.png 设置别名为 about.png。前缀都是 logo,只不过第二个设置了语言环境属性为 fr。那就意味着,当我本机为法语时,程序会从第二个前缀中找叫 about.png 的文件。

 两种资源路径

假设已经加载好资源,访问这些资源的两种方式是:

  • 文件路径「:/images/about.png」
  • URL「qrc:///images/about.png」
     

如何加载资源

加载资源有两种,一种是直接将资源数据存储在可执行文件中(静态方式),另一种是将资源数据存储在单独的二进制文件中并由可执行文件调用(动态方式)。

 静态方式

除了用 Qt Creator 在工程中添加 qrc 文件以外,需要在 pro 文件中加入 qrc 文件以便 qmake 能识别资源文件,一般这步会被自动添加。例如:

RESOURCES = resource.qrc  

qmake 编译后会生成一个名为 qrc_resource.cpp 的文件,打开它我们会看到刚才我们的资源已经以静态数组的形式保存在了该文件中。最终该文件的数据会存入可执行文件中。

 动态方式

动态方式不需要写 pro 文件,需要手动用 rcc 工具编译 qrc 文件,然后用 QResource 类加载。

(1)手动用 rcc 工具编译 qrc 文件。

rcc -binary resource.qrc -o resource.rcc 

(2)在程序中使用 QResource 类加载。

QResource::registerResource("/path/resource.rcc");

备注:rcc 工具的使用请参考官方文档“Resource Compiler (rcc)”。

 

在lib库中使用资源

一般我们写完 lib 库后提供给外界的就是一个库文件和头文件,所以无论你是在库中使用资源还是给外界提供资源,最好是采用静态方式。不然的话你还得额外提供 rcc 文件,即独立的二进制资源文件。

将资源存储于 lib 库中,需要调用 Q_INIT_RESOURCE() 宏来强制资源初始化。反之如果卸载资源则调用 Q_CLEANUP_RESOURCE(),例如:

MyClass::MyClass():BaseClass()
{
   Q_INIT_RESOURCE(resources);
   QFile file(":/myfile.dat");
   ...
}

 

这样可以确保在静态链接的情况下将资源链接到最终的应用程序二进制文件中。您应该将初始化代码放置在库中资源使用的位置附近,以便库客户端仅在使用依赖于资源的库功能时才链接资源。

注意:由于rcc生成的资源初始化器是在全局名称空间中声明的,因此您对Q_INIT_RESOURCE()的调用也需要在任何名称空间之外进行。

如果库包含的资源不是内部使用的,而是暴露给库的客户端的,则初始化需要在应用程序代码中进行。例如:

 

注意:在程序而不是库中,如果采用静态方式,不需要使用Q_INIT_RESOURCE() 和 Q_CLEANUP_RESOURCE()。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值