0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Qt资源系统,再也不用担心按钮图标不见了

嵌入式小生 来源:嵌入式小生 2023-02-21 09:41 次阅读

一、资源系统

Qt的资源系统是一种独立于平台的机制,目的是用于在应用程序的可执行文件中存储二进制文件。资源系统基于qmake、Qt的资源编译器(rcc)和QFile实现。如果应用程序总是需要一组特定的文件(例如图标、翻译文件等),并且不想让这些文件丢失而影响应用程序的功能,这时候则可以使用Qt资源系统解决这个问题。

二、外部二进制文件

Qt对于外部的二进制文件,如果需要使用这个二进制文件,那么则必须将所需要使用的二进制文件转换成Qt的资源数据文件(默认文件名后缀为.rcc)。转换步骤如下:

在Windows命令行下(这里以Windows系统为例),输入以下命令:

82130b44-b184-11ed-bfe3-dac502259ad0.png

备注:这里windows命令行工作区目录需要切换到.qrc文件所在的文件夹下,如上,笔者的工程项目的.qrc文件位于上述文件路径。然后再输入上述命令,便可使用rcc工具生成对应的资源文件。如下图:

82378168-b184-11ed-bfe3-dac502259ad0.png

上图所示目录下的rc.rcc则是生成的资源文件。资源文件生成完成后,如何在应用程序中使用呢?

(1)在应用程序中使用registerResource()注册资源,如下代码:

#include"widget.h"

#include
#include
#include

intmain(intargc,char*argv[])
{
QApplicationa(argc,argv);

//资源文件的路径
QStringrccPath="C:/Users/iriczhao/Documents/untitled6/rc.rcc";

//注册资源文件
if(!QResource::registerResource(rccPath))
{
qDebug()<<"rcc register failed!";
    }

    Widget w;
    w.show();
    
    return a.exec();
}

(2)默认情况下,在应用程序中,可以使用与资源树中相同的文件名访问资源,使用 :/ 前缀,或者使用qrc模式的URL访问资源。例如,文件路径:/images/top_bk.png或URL qrc:///images/top_bk.png将提供对top_bk.png文件的访问,该文件在应用程序资源树中的位置是images/top_bk.png。

如果不需要资源文件了,可以使用unregisterResource()卸载注册的资源。

本小节描述的资源文件使用方法是:rcc+QResource。这种方式在发布应用软件时需要连资源文件一起发布,并且需要保证资源的路径与应用程序中设置的一致。除了这种方式,还可以将资源与应用程序编译成二进制文件,后文会继续写到。

在内存中,资源由资源对象树表示,该树在启动时自动构建,并由QFile解析资源的路径。我们可以使用:/初始化的QDir从资源树根开始地方进行资源导航和搜索。Qt的资源系统支持搜索路径列表,如果使用:而不是:/作为前缀引用资源,则将使用搜索路径列表查找该资源。搜索路径列表在启动时为空;需要调用QDir::addSearchPath()添加资源搜索路径。

三、将资源与应用程序编译成二进制文件

方法如下:

在工程文件.pro中,新增RESOURCES变量,如下:

RESOURCES=application.qrc

application.qrc为资源描述文件。还可以通过QtCreator的资源创建对话框添加。

这样在应用程序构建中,资源文件将会与应用程序一起构建成统一的整体,如下图所示:

824ede1c-b184-11ed-bfe3-dac502259ad0.jpg

通过这种方式,Qt总是将资源数据与应用程序编译构建在一起。这样就不必担心丢失资源的问题,但是会为需要编译的资源开设内存空间,对硬件资源严苛的环境并不友好。

四、使用库中的资源

如果资源在库中,若需要使用库中资源,则需要调用Q_INIT_RESOURCE()强制初始化资源,将.qrc文件的资源名传入到Q_INIT_RESOURCE()中。例如:

MyClass::MyClass():BaseClass(){
Q_INIT_RESOURCE(resources);//强制初始化资源

QFilefile(":/myfile.dat");
...
}

这种方式确保了在静态链接的情况下,资源被链接到最终的应用程序二进制文件中。在实际开发中,应该将初始化代码放在库中使用资源的位置附近,这样,如果基于库的应用程序使用了依赖于它们的库的特性,那么它们将只链接这些资源。

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

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

intmain(intargc,char*argv[]){
QApplicationapp(argc,argv);
Q_INIT_RESOURCE(graphlib);

QFilefile(":/graph.png");
...
returnapp.exec();
}

这可以确保在静态链接的情况下将资源链接到最终的应用程序二进制文件中,但在动态链接的情况下(如插件)也会触发库加载。

同样,如果必须显式卸载一组资源,可以调用Q_CLEANUP_RESOURCE()来强制删除资源,传入的参数是.qrc资源文件名称。

注意:当资源作为应用程序的一部分构建时,Q_INIT_RESOURCE()和Q_CLEANUP_RESOURCE()是不必要的。

五、资源压缩

Qt资源压缩是指:利用Qt的资源编译器(rcc)对资源文件(.qrc)中提到的资源进行压缩处理,以此方式优化最终二进制文件占用磁盘空间的情况 。默认情况下,它将执行自发式检查,以确定压缩是否值得,如果压缩不够,它将存储未压缩的内容。Qt资源文件的压缩有如下特点:

(1)可以设置压缩的压缩阈值(threshold)。

(2)可以打开或关闭压缩功能。

(3)可以设置压缩等级。

(4)rcc支持以下压缩算法和压缩等级:

序号 压缩方式 描述
1 zstd 使用Zstandard库来压缩内容。有效的压缩级别范围从1到19,1是最小的压缩(耗费最少的CPU时间),19是最大的压缩(耗费最多的CPU时间)。默认级别为14。特殊值0告诉zstd库选择一个实现定义的默认值。
2 zlib 使用zlib库压缩内容。有效的压缩级别范围从1到9,1是应用最少的压缩(耗费最少的CPU时间),9是应用最多的压缩(耗费最多的CPU时间)。特殊值0表示“不压缩”,实际开发中不应使用。默认通常是级别6。
3 none 没有压缩。与-no-compress选项相同。

六、总结

总而言之,Qt框架对应用程序的资源有两种使用、控制方式:

(1)第一种是直接将资源(如图片、图表)等与应用程序一起构建编译,通过这种方式,资源数据将会与应用程序成为整体,不用担心资源数据的丢失问题,但是对于内存资源严苛的环境并不友好。

(2)第二种是通过QResource类API动态的注册和卸载资源数据文件(也称为动态资源引入)。这样在程序的运行中能动态的加载、引入资源数据,便于资源数据的管理和使用,同时也缩小了应用程序的内存占用空间。在Qt框架中,使用的外部资源文件(二进制)必须是.rcc文件。这种文件需要使用Qt资源编译器(RCC)工具进行编译、处理、生成,然后使用QResource类进行.rcc文件的注册和卸载操作,动态的在应用程序运行过程中使用资源文件。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • WINDOWS
    +关注

    关注

    3

    文章

    3515

    浏览量

    88275
  • 编译器
    +关注

    关注

    1

    文章

    1614

    浏览量

    49002
  • Qt
    Qt
    +关注

    关注

    1

    文章

    301

    浏览量

    37761
  • 资源系统
    +关注

    关注

    0

    文章

    2

    浏览量

    5280
  • 命令行
    +关注

    关注

    0

    文章

    77

    浏览量

    10370

原文标题:Qt资源系统,再也不用担心按钮图标不见了

文章出处:【微信号:嵌入式小生,微信公众号:嵌入式小生】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ST-Link驱动不见了怎么解决?

    用了很久的ST-Link驱动突然不见了,重新安装设备管理器里面也没有,电脑重启也没用,到底怎么了,应该怎么办?[/tr]
    发表于 03-18 06:37

    显示桌面不见了怎么办?任务栏和xp显示桌面图标不见了?

    显示桌面不见了怎么办?任务栏显示桌面不见了?工具栏显示桌面不见了?xp显示桌面不见了 ?显示桌面图标不见
    发表于 06-19 10:44

    AD09 PCB飞线不见了怎么办?

    大家好,AD09 PCB飞线不见了怎么办?
    发表于 03-27 14:04

    Win7笔记本任务栏中的电源图标不见了怎么办

    Win7任务栏中的电源图标不见了怎么办:很多时候我们需要将自己的笔记本电脑带出门,因此电量就是我们最关注的问题了,因为不是每个地方都有电源的,但是最近有些用户发现Windows7系统的任务栏通知区域
    发表于 05-21 16:20

    PSIM为什么背景变白,电路图不见了

    之前画好的电路图,不知道点到哪了,电路图就不见了,背景也变白了,但是运行还是正常的,这是怎么回事,怎么才能把电路图显示出来
    发表于 04-23 09:44

    pcb文件打开时贴片焊盘不见了

    本帖最后由 feifeigg5854 于 2015-6-25 19:23 编辑 pcb文件打开时贴片焊盘不见了,请各位大虾看看是怎么回事!
    发表于 06-18 14:17

    PCB布线,网络飞线不见了

    PCB布线时,网络飞线不见了,但是只是其中一个网络飞线不见,代之的是红色X号方框,大家遇到过吗?
    发表于 01-09 20:52

    Win10系统的回收站不见了的解决方法

    设置中点击“桌面图标设置”快捷链接。5、在打开的“桌面图标设置”窗口中,发现回收站没有选中,我们在这里选中“回收站”前的勾选,点击确定按钮。接下去的精彩内容请看:Win10系统的回收站
    发表于 01-27 16:20

    labview出报表excel横线不见了

    labview出报表的时候,excel模板里面有横线,但是一生成报表的时候,为什么线就不见了?见图红线部分,请问该怎么办,谢谢
    发表于 08-10 15:52

    奇葩的问题,簇的边框不见了

    奇葩的问题,簇的边框不见了。 众所周知,簇在面板显示的时候,有个边框,就是凹进去的那个,让你知道那是个簇。最近看了07年的程序,竟然没有边框。??如下:上一个主题:https://bbs.elecfans.com/jishu_938887_1_1.html
    发表于 09-16 14:42

    生成exe时出错,源程序不见了怎么解决?

    生成exe时出错,源程序不见了怎么解决?打开以后就成现在这样了,求大神指教
    发表于 01-17 18:42

    为什么我的原理图编译过来封装不见了

    为什么我的原理图编译过来元器件我的线都还在怎么封装不见了,感觉封装没错啊
    发表于 06-05 03:03

    为什么AD17拼板后泪滴不见了

    AD17使用复制、特殊粘贴后拼板,泪滴不见了,哪位高手知道怎么处理,谢谢!发现AD18、AD19都有这个问题。AD09倒是不会。
    发表于 09-29 10:03

    垃圾箱删除了不见了怎么办

    垃圾箱删除了不见了怎么办 上回我的电脑不小心把垃圾箱给删除了,死活不见了,现和大家分享一下我找回来的方法: 1 在空白的电脑桌面,按右
    发表于 12-23 14:46 1.7w次阅读
    垃圾箱删除了<b class='flag-5'>不见了</b>怎么办

    快速启动栏显示桌面图标不见了如何恢复

    很多电脑用户在使用电脑时会出现桌面上的图标不见了,有的是快快速启动栏显示桌面图标不见了,不知道怎么找回来,这跟操作有很大的关系,下面介绍几种常用的关于快速启动栏显
    发表于 10-16 11:06 3.2w次阅读