• 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 助手
  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/itrena/p/5938249.html
Copyright © 2020-2023  润新知