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 助手

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
一.前提条件 1.纯熟扎实的语言基础   如果你学java,却对反射、泛型、注解一直半解,还是不要去读什么框架了,回去把java基础打扎实反而对你自身更有益。 2.UML能力   在软件工程中,UML在软件的不同生命周期阶段扮演着非常重要的角色,没有好的UML水平,面对大型的项目源码会束手无策。 3.对业务的理解   如果你要阅读的项目业务性比较强,事先对业务有一定的了解是必须的。 4.设计模式、重构的掌握   编程语言什么的没什么好说。着重提一个:设计模式由于Android源代码用到各种各样的设计模式,
在上一篇博文《 LTE下行物理层传输机制(7)-DCI2格式和预编码矩阵的选择 》中已经提到,如果当前UE的传输模式是TM4,且可以执行空分复用(一个PDSCH信道传输2个TB块),那么需要采用DCI2格式来承载控制信息域,使用的预编码矩阵需要参考UE反馈的PMI值,因此属于闭环性质的空分复用。相应的,LTE系统中也有一种开环的空分复用: 如果当前UE的传输模式是TM3,且可以执行空分复用,那么此时PDCCH需要采用DCI2A格式发送,这时的空分复用就属于开环性质的空分复用,不需要参考UE反馈的PMI值。
好久没写android的博客,最近在做一个android的项目,里面用到我们经常用的一个控件就是对话框,大家都知道android自带的对话框是很丑的,android5.x之后除外.所以就出现了自定义view,自己定义美观的对话框.好我们就来自定义对话框. 整体思路:定义一个类然后去继承Dialog类,然后重写相应的构造器方法.大家都知道一般的对话框的创建过程都是来一个AlertDialog.Builder对象,然后使用一些set方法来设置标题内容以及设置一些自定义的view和点击的Button以及相应的点
1.android 的UI线程阻超过5秒就会引发ANR(Application not responding)异常,如果等待超过3秒,你就会失去用户。 2.在android中组件的启动线程被称为主线程(也称UI线程),一般不在这线程中进行耗时的工作,所以我们将线程分为两种,分别是main thread和worker thread,当应用程度运行是时,系统默认的启动线程就是主线程,主要用来加载UI,完成和用户间的交互,所有这些都在同一个线程中进行,所以不能在这个线程中进行耗时工作,不能阻塞UI,androi
接触过自定义控件的开发者一看,笑了,立马关了网页。但是…你真的知道怎么绘制居中文本吗? 我不会?开玩笑,不就是: X=控件宽度/2 - 文本宽度/2;Y=控件高度/2 + 文本宽度/2 好吧,那我试一下。 1.自定义控件基本步骤 自定义View的属性 在View的构造方法中获得我们自定义的属性 #重写onMesure # 重写onDraw OK,简单,直接干起来。 1. 自定义View的属性 按照最简单的来,属性有:文本,文本颜色,文本大小。 我们在 /value/attrs.xml 中这么写: ?xml
首先,自定义控件分为三类: 自定义的组合控件 继承View的自定义控件 继承ViewGroup的自定义控件 在这里,我要写的是第二种,也就是继承自View的自定义控件,第一种自定义的组合控件,我已经写过了,可以在我的博客中可以找到 现在来看一下继承View的自定义控件 首先,需要写一个类继承自View,那么,它也有三个构造方法,有一个参数的构造方法实在代码中new这个自定义控件时被调用;有两个参数的构造方法是在布局中使用这个自定义控件的时候调用,有三个参数的构造方法,实在使用到这个自定义控件的样式时被调用

WindowManager的分析 - 2016-07-22 18:07:46

一、Window和WindowManager Window:表示一个窗口,从下面Window的源码中可以看出它有且只有一个实现类PhoneWindow。 The only existing implementation of this abstract class is * android.policy.PhoneWindow, which you should instantiate when needing a * Window. WindowManager:它是系统提供我们操作Window的一个接口

MTK6580-Psensor hal层驱动分析 - 2016-07-22 18:07:25

一、HAL 层Sensor 流程         Hal 就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux内核驱动程序运行在内核空间。 Sensor 打开设备时序图:  其中SensorDevice 属于 JNI 层,与 HAL 进行通信的接口 ; 在 JNI 层调用了 HAL 层的 open_sensors() 方法
ART世界探险(2) - 从java byte code说起 Dalvik时代,如果不做JIT的话,只需要了解java字节码和Dalivk的字节码就够了。但是,到了ART时代,我们可能还要至少学习两种新东西:一个是编译后端的IR中间代码。比如,我们假如使用LLVM做为编译后端的话,需要做从dex到LLVM IR的转换工作。这个IR可能还不只一层,比如分中层的MIR和底层的LIR。 最后,我们还得了解机器指令。仅就ARM来说,现在是64位时代了,我们需要了解的就是AArch64和AArch32两种状态下的A

使用AndFix实现Android热修复 - 2016-07-22 18:07:19

AndFix Github: https://github.com/alibaba/AndFix AndFix介绍 AndFix是一个Android App的在线热补丁框架。使用此框架,我们能够在不重复发版的情况下,在线修改App中的Bug。AndFix就是 “Android Hot-Fix”的缩写。  就目前来说,AndFix支持Android 2.3到6.0版本,并且支持arm 与 X86系统架构的设备。完美支持Dalvik与ART的Runtime。  AndFix 的补丁文件是以 .apatch 结