Qt资源使用的方式

目录

一、概述

二、qrc资源静态使用

1、在qrc文件中加入图片

2、qrc资源编译cpp文件

3、资源的使用

三、qrc资源动态使用

1、概述

2、资源注册和反注册源码

3、使用方法

四、I/O读取


一、概述

        Qt资源体系采用平台独立机制来存储应用程序执行时的二进制文件。这种机制在应用程序需要一些确定的文件(图标、翻译文件等等)而且又不想冒丢失文件的风险时是有用的。资源体系依赖于 qmake, rcc (Qt’sresource compiler), 和 QFile 的紧密协作。Qt3 的 qembed 工具和  image 
collection 机制被废除。

二、qrc资源静态使用

1、在qrc文件中加入图片

 2、qrc资源编译cpp文件

/****************************************************************************
** Resource object code
**
** Created: Sun Oct 23 19:57:12 2022
**      by: The Resource Compiler for Qt version 4.8.4
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include <QtCore/qglobal.h>

static const unsigned char qt_resource_data[] = {
...//省略了图片数据
  // D:/documents/visual studio 2010/Projects/testWidget/testWidget/test.png
 
  
};

static const unsigned char qt_resource_name[] = {
  // testWidget
  0x0,0xa,
  0x9,0xd0,0xf4,0x84,
  0x0,0x74,
  0x0,0x65,0x0,0x73,0x0,0x74,0x0,0x57,0x0,0x69,0x0,0x64,0x0,0x67,0x0,0x65,0x0,0x74,
    // test.png
  0x0,0x8,
  0xc,0xa7,0x58,0x7,
  0x0,0x74,
  0x0,0x65,0x0,0x73,0x0,0x74,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67,
  
};

static const unsigned char qt_resource_struct[] = {
  // :
  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
  // :/testWidget
  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
  // :/testWidget/test.png
  0x0,0x0,0x0,0x1a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,

};

QT_BEGIN_NAMESPACE

extern Q_CORE_EXPORT bool qRegisterResourceData
    (int, const unsigned char *, const unsigned char *, const unsigned char *);

extern Q_CORE_EXPORT bool qUnregisterResourceData
    (int, const unsigned char *, const unsigned char *, const unsigned char *);

QT_END_NAMESPACE


int QT_MANGLE_NAMESPACE(qInitResources_testwidget)()
{
    QT_PREPEND_NAMESPACE(qRegisterResourceData)
        (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_testwidget))

int QT_MANGLE_NAMESPACE(qCleanupResources_testwidget)()
{
    QT_PREPEND_NAMESPACE(qUnregisterResourceData)
       (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_testwidget))

      对于这种方式:其是将所有的图片资源都转化成二进制数据,存放在一个静态数组中,而后放到应用程序中。所以:当程序执行时:所有图片都会一直在内存中,这杨虽然读取速度很快,但是很占用内存空间,对于一些内存有限的设备不是很适合。

        当编译时,其会将我们写的 name.qrc文件转换生成一个qrc_name.cpp的资源文件,我们可以自己看下这个生成的cpp文件,发现其中就是主要有三个static const数组。

              qt_resource_data[]

              qt_resource_name[]

              qt_resource_struct[]

       这其中qt_resource_data[]中存放的就是图片的二进制数据。 qt_resource_name是图片资源的一些名字的数组。qt_resource_struct目前还没明白具体意思。

#ifndef Q_CONSTRUCTOR_FUNCTION
# define Q_CONSTRUCTOR_FUNCTION0(AFUNC) \
   static const int AFUNC ## __init_variable__ = AFUNC();
# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)
#endif
#ifndef Q_CONSTRUCTOR_FUNCTION
# define Q_CONSTRUCTOR_FUNCTION0(AFUNC) \
   static const int AFUNC ## __init_variable__ = AFUNC();
# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)
#endif

        Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_testwidget))会定义一个全局静态变量调用qInitResources_testwidget这个函数,将数据注册到Qt内部中。同一应用程序下的不同模块,可以共享这个资源。

        使用这种方法时,由于图片资源一直在内存中,避免了I/O操作,从而加快了读取速度。但是却是以消耗内存为代价的。

3、资源的使用

QIcon Icon(":/testWidget/test.png");
this->setWindowIcon(QIcon(":/testWidget/test.png"));

三、qrc资源动态使用

1、概述

         第一种方法相当于静态加载,但很多情况下我们更希望是动态加载,亦即:用到哪个资源才将该资源加载进来,而不用的则不加载。上边第一种方法之 所以显示出静态加载的特性,这是由于系统一次性自动把所有图片资源都进行了注册,并且在程序运行过程中一直没有进行反注册才导致的。  如果我们可以自行决定:什么时候对那一部分图片资源进行注册?什么时候对哪一部分图片资源进行反注册。则显然我们可以手动控制整个资源在内存中的生存周 期。

        图片是一种资源,而在Qt中,对于资源的使用是有独特的方式的。一般来说:资源在内存中是用资源对象树来表示的,该树在程序启动时创建而对于资源而言:我们都是需要先将其加入到这棵树才能加载到内存中并被程序使用而将一个图片资源放到程序的资源对象树是用函数QResource::registerResource()来实现的。亦即:要将资源向这颗资源对象树进行注册,这样才对在系统中new创建这个资“叶子”。          

2、资源注册和反注册源码


bool QResource::registerResource(const QString &rccFilename, const QString &resourceRoot)
       {
            QString r = qt_resource_fixResourceRoot(resourceRoot);
            if(!r.isEmpty() && r[0] != QLatin1Char('/'))
 
            {
                 qWarning("QDir::registerResource: Registering a resource [%s] must be rooted in an absolute path (start  with /) [%s]",
                 rccFilename.toLocal8Bit().data(), resourceRoot.toLocal8Bit().data());
                 return false;
            }
 
            QDynamicFileResourceRoot *root = new QDynamicFileResourceRoot(r);
            if(root->registerSelf(rccFilename))
 
            {
                 root->ref.ref();
                 QMutexLocker lock(resourceMutex());
                 resourceList()->append(root);
                 return true;
            }
           delete root;
           return false;

     

bool
    QResource::unregisterResource(const QString &rccFilename, const QString &resourceRoot)
    {
          QString r = qt_resource_fixResourceRoot(resourceRoot);
 
          QMutexLocker lock(resourceMutex());
          ResourceList *list = resourceList();
          for(int i = 0; i < list->size(); ++i)
 
          {
               QResourceRoot *res = list->at(i);
               if(res->type() == QResourceRoot::Resource_File)
 
               {
                    QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
                     if(root->mappingFile() == rccFilename && root->mappingRoot() == r)
 
                     {
                         resourceList()->removeAt(i);
                          if(!root->ref.deref())
 
                          {
                              delete root;
                              return true;
                          }
                          return false;
                    }
               }
           }
           return false;
   }

3、使用方法

       这种方法的主要步骤为:

       (1)生成外部二进制资源文件。

       (2)在需要时将该资源向程序的资源对象树进行注册并使用。

       (3)在不需要时进行反注册。

      步骤(1)主要是用了Qt自带的一个工具:rcc.exe  (处于bin文件夹中)。这是Qt的一个资源编译器,其编译对象是qrc文件,而生成rcc二进制资源文件。

      那我们可以用它来执行命令 rcc -binary name.qrc -o name.rcc  来把qrc资源文件转成rcc二进制资源文件。在程序初始化时将rcc文件注册一下即可。

int main()
{
...
     QResource::registerResource(rcc文件路径);
...
}

四、I/O读取 

QIcon("./bmp/name.png");
QIcon::QIcon ( const QString & fileName )
Constructs an icon from the file with the given fileName. The file will be loaded on demand.

If fileName contains a relative path (e.g. the filename only) the relevant file must be found relative to the runtime working directory.

The file name can be either refer to an actual file on disk or to one of the application's embedded resources. See the Resource System overview for details on how to embed images and other resource files in the application's executable.

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kupeThinkPoem

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值