Qt、C++动态UI

Qt、C++动态UI

  • 一、简介
  • 二、QUiLoader
  • 三、Qt插件
    • 1、项目创建
    • 2、插件使用
    • 3、效果预览
  • 四、Qt资源管理
    • 1、创建`.qrc`
    • 2、内嵌资源
    • 3、外挂资源
  • 五、小结

一、简介

在项目实践中,最简单的更新应用UI交互的方式就是更新整个安装包。

随着业务的发展,一个客户端需要同时适配多种业务,每种业务都有自己独特的设置页,业务之间又较为独立。如果将这些UI页面、业务代码都在一份代码上维护,加各种条件分支,维护会越来越困难:容易出错、程序体积增大、测试工作量增加,而且无法满足快速迭代的需求。

因此,如果能针对不同业务,提供各异的插件、描述文件动态更新UI交互,就能比较好的满足业务需求。而且动态UI只需要更新插件、描述文件,也能够运行时更新,对用户体验、客户端其它功能影响能够降到非常低。

本文基于Qt(5.12.12)、C++客户端开发(Visual Studio 2017),整理了一套较为完善的动态UI方案。
Qt、C++动态UI_第1张图片
Qt提供了QUiLoader,支持在程序运行时,加载.ui(Qt定义的XML)来动态更新UI页面,还能以Qt插件的方式将自定义控件也加入.ui。另外,还可以通过运行时加载rcc文件的方式,动态更新指定程序所用资源,包括图标、动图、样式表等等;同时,也能减少程序包体积,比如将不常用到的资源在需要用到时再下载解析。当然,样式表.qss本身就支持运行时加载,常用于程序换肤功能。

本文从QUiLoader加载UI页面出发,围绕Qt、C++动态加载UI,较全面的介绍QUiLoader、Qt资源管理、Qt插件的创建及使用。

二、QUiLoader

使用QUiLoader需要引入模块UI tools。模块引入后exe体积增长情况如下:

exe体积增长
release 约436KB
debug 约907KB

将.ui添加到.qrc,或指定绝对路径,参考下面代码:

QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    QUiLoader loader;
    QFile file(":/QtWidgetsApplication1/Widget.ui");
 /* 或QFile file(R"(E:/work src/test/QtWidgetsApplication1/QtWidgetsApplication1/Widget.ui)"); */
    file.open(QFile::ReadOnly);
    QWidget *myWidget = loader.load(&file, this);
    file.close();

    auto *layout = new QVBoxLayout;
    layout->addWidget(myWidget);
    ui.centralWidget->setLayout(layout);
}

先用QFile从指定路径负责读取.ui,然后调用QUiLoader::load接口从.ui中加载出QWidget*,再将该QWidget*添加到指定父页面上。当然,经过在Qt5.12.12上的实践,.ui也可以是由QWidget、QDialog、QFrame或QMainWindow等作为顶层窗体。另外,.ui 的顶层窗体可以有布局,也可以是没布局。可见,基本上通过Qt Designer能生成的.ui,QUiLoader都能动态加载出来。

相比于直接把.ui转成C++代码编进程序,QUiLoader支持在运行期间直接根据.ui生成对应页面,提供了更大的可能性,比如同一份.ui可以在完全不同的业务中加载出来,而无需依赖某个类或.h。

另外,如果需要在QUiLoader加载的.ui页面跟程序中connect信号、槽,可以通过下面方式查找对象、定义信号/槽:

/* 1.查找名称为“testBtn”QPushButton */
QPushButton *getButton = getWidget->findChild<QPushButton *>("testBtn"); 
 
/* 2.查找所有QPushButton */
QList<QPushButton *> getAllPButtons = getWidget->findChildren<QPushButton *>();
QMetaObject::connectSlotsByName(this); /* 该函数会将this的所有子对象都连接上一个槽(slot),槽的命名规范为on_对象名_信号名,比如上面的setButton的clicked(),将会生成一个on_setButton_clicked()的槽,你只要实现该槽函数就可以了 */

在实际项目中,.ui往往并非由Qt基本控件、基本样式组成,我们还需要往.ui里面添加一些自定义控件。

Qt官方文档中没有描述当.ui包含自定义控件时,如何用QUiLoader加载。按照传统.ui转成C++编进exe的方式,将基本控件“提升为”项目中的自定义控件类,如派生自QWidget的子类CustomWidget,用QUiLoader加载.ui,CustomWidegt“退化为“普通的QWidget,且errorString()不会输出任何错误。

重新看了下QUiLoader的接口,发现QUiLoader提供了void QUiLoader::addPluginPath(const QString& path)接口,因此QUiLoader支持的应该是通过Qt插件添加自定义控件的方式。

我们可以基于QtUiPlugin/QDesignerCustomWidgetInterface创建Qt插件,而Qt+VS也提供了创建这种插件项目的方式,接下来一章我们阐述下Qt插件及其创建和应用。

三、Qt插件

1、项目创建

基于Qt5.12.12版本,你可以创建Qt插件项目,
Qt、C++动态UI_第2张图片
本文创建的Qt插件项目,命名为CustomWidget。创建完项目后,就会默认生成CustomWidgetPlugin类:

#pragma once

#include 

class CustomWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface" FILE "customwidgetplugin.json")
    Q_INTERFACES(QDesignerCustomWidgetInterface)

public:
    CustomWidgetPlugin(QObject *parent = Q_NULLPTR);

    bool isContainer() const;
    bool isInitialized() const;
    QIcon icon() const;
    QString domXml() const;
    QString group() const;
    QString includeFile() const;
    QString name() const;
    QString toolTip() const;
    QString whatsThis() const;
    QWidget *createWidget(QWidget *parent);
    void initialize(QDesignerFormEditorInterface *core);

private:
    bool initialized;
};

CustomWidgetPlugin的基类QDesignerCustomWidgetInterface定义了比较完备的接口(纯虚函数),

class QDesignerCustomWidgetInterface
{
public:
    virtual ~QDesignerCustomWidgetInterface() {}

    virtual QString name() const = 0;
    virtual QString group() const = 0;
    virtual QString toolTip() const = 0;
    virtual QString whatsThis() const = 0;
    virtual QString includeFile() const = 0;
    virtual QIcon icon() const = 0;

    virtual bool isContainer() const = 0;

    virtual QWidget *createWidget(QWidget *parent) = 0;

    virtual bool isInitialized() const { return false; }
    virtual void initialize(QDesignerFormEditorInterface *core) { Q_UNUSED(core); }

    virtual QString domXml() const
    {
        return QString::fromUtf8("")
            .arg(name()).arg(name().toLower());
    }

    virtual QString codeTemplate() const { return QString(); }
};

2、插件使用

CustomWidget插件项目的编译产物是CustomWidget.dll或CustomWidget.lib,在实际项目代码中可以单独使用上述CustomWidget.dll或CustomWidget.lib,不引入额外的.h,因为接口名称都是QDesignerCustomWidgetInterface定义好的。

一般可以通过QPluginLoader来加载Qt插件,并且QPluginLoader提供了load、unload接口支持热更新。示例代码如下:

QPluginLoader pluginLoader("CustomWidget.dll"); /* 相对路径,根据实际路径传入 */
if (pluginLoader.load())
{
 	if (QObject *pPlugin = pluginLoader.instance())
	{
		auto *pCustomWidgetPlugin = dynamic_cast<QDesignerCustomWidgetInterface *>(pPlugin);
		auto *pLayout = new QVBoxLayout;
		pLayout->addWidget(pCustomWidgetPlugin->createWidget(this));
		ui.centralWidget->setLayout(pLayout);
	}
}

CustomWidgetPlugin::createWidget本质上是只是执行了一段创建自定义控件的逻辑,因此在createWidget之后执行pluginLoader.unload()卸载插件,不会影响已创建的自定义控件。

上述创建的CustomWidget插件工程目录如下:
Qt、C++动态UI_第3张图片
其中,为了方便,我添加了CustomWidget.ui用于设计CustomWidget的UI样式。

3、效果预览

Qt本身提供的大多数工具都是支持上述Qt插件的,包括Qt Creator、Qt Designer等等。我们开发和使用插件项目时,也会希望能实时预览插件在项目中的效果,那么就可以把开发的插件“添加”到Qt Designer中去。

我使用的是Visual Studio 2017+Qt5.12.12开发,需要将CustomWidget.dll放到

D:\Qt\Qt5.12.12\5.12.12\msvc2017\plugins\designerD:\Qt\Qt5.12.12\5.12.12\msvc2017_64\plugins\designer

注意,需要保证32位、64位对应,否则Qt Designer识别不到。

你可以打开Qt Designer,在帮助-关于插件中刷新查看CustomWidget.dll的加载情况,
Qt、C++动态UI_第4张图片
上面是因为我放的CustomWidget.dll是debug版本,而Qt Designer要求使用release版本,重新编译放置后,
Qt、C++动态UI_第5张图片
在Qt Designer中,添加到.ui并加载出来了我所创建的Qt插件CustomWidget.dll,Qt Designer本身有预览效果的功能:

QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    QUiLoader loader;
    loader.addPluginPath(R"(E:/test/QtWidgetsApplication1/Release/)");
    QFile file(R"(E:/work src/test/QtWidgetsApplication1/QtWidgetsApplication1/Widget.ui)");
    file.open(QFile::ReadOnly);
    QWidget *myWidget = loader.load(&file, this);
    file.close();
    const auto result = loader.errorString();
    auto *layout = new QVBoxLayout;
    layout->addWidget(myWidget);
    ui.centralWidget->setLayout(layout);
}

Qt Designer中预览效果:
Qt、C++动态UI_第6张图片
图中“插件子页面”文本所示Widget即插件显示效果。为了验证效果,只是简单的添加了个文本,在.ui中给CustomWidget设置了样式如下:

background-color: rgb(170, 255, 255)

实际加载CustomWidget.dll效果:
Qt、C++动态UI_第7张图片
另外,发现release的工程能加载release和debug的插件,但debug的工程只能加载debug的插件,若加载release的插件依然失败,且errorString()不输出任何问题。

QUiLoader加载Qt插件后,还可以通过QUiLoader::availableWidgets接口自由创建插件对应的UI页面,

QWidget *loadCustomWidget(QWidget *parent)
{
    QUiLoader loader;
    QWidget *myWidget;

    QStringList availableWidgets = loader.availableWidgets();

    if (availableWidgets.contains("CustomWidget"))
        myWidget = loader.createWidget("CustomWidget", parent);

    return myWidget;
}

完成了带自定义控件的.ui加载之后,还有一个问题,就是.ui可能包含一些图标、项目中复用的样式(如皮肤)资源,通常通过.qrc来进行加载。

而我们运行时动态加载的.ui本身是不包含.qrc的,那么这个.ui中的图标、样式怎么加载呢?

四、Qt资源管理

在Qt中,我们既可以用Qt Designer直接在.ui中指定控件的图标资源路径(样式表的规则可以参考我的另一篇博客),
Qt、C++动态UI_第8张图片
也可以在使用具体Qt控件时传入路径,

QPixmap testPixmap(":/QtWidgetsApplication1/src/qt.png");
QRect testRect; /* TODO:赋值 */
painter->drawPixmap(testRect.x(), testRect.y(), testPixmap, testRect.width(), 0, testRect.width(), testRect.height());

而上述图标路径跟具体某个.qrc无关,即程序运行后如果有一个.qrc中包含该路径资源,就能加载出对应图标。

通过实践发现,如果在.ui中添加或不添加图标资源对应的.qrc,不影响最终程序运行时该图标的加载,只是在Qt Designer中无法根据.ui预览该图标。

也就是说,不光是本文中用QUiLoader运行时加载的Widget.ui中使用了某个图标资源路径,还是Qt插件CustomWidget.dll中使用了,只要程序运行时存在任意一份.qrc里包括了该图标资源,就能成功加载出来。

当然,如果运行时程序中没有找到任何匹配的图标资源,就会不显示任何图标,但不影响程序运行。

如下图所示,红色框中是QUiLoader在程序运行时加载的图标,黄色框中是插件创建页面中的图标,蓝色框中才是程序本身代码中指定图标,而这三个图标路径都是对应程序编译进去的同一个.qrc中同一个图标。
Qt、C++动态UI_第9张图片
不过,正如本文简介中提到,我们想要的图标、样式资源可能仅用于运行时才加载的.ui或插件,并不希望程序中本身就包括,这样才能支持运行时连同图标、样式一起更新。

那么,在运行时怎么指定和加载.ui专属的.qrc呢?

我们还是先来回顾下.qrc的基本知识。

.qrc,是Qt提供的用于管理资源的文件格式,它有两个非常有用的特点:

  • 延迟加载:即当你首次调用某个资源时才会申请内存。

  • 资源复用:当你多个地方同时调用同一资源,Qt不会重复申请内存。

.qrc就相当于使用了一个强化版本的fileCache。

1、创建.qrc

通常可以通过下图所示创建.qrc并添加到项目中,
Qt、C++动态UI_第10张图片
我们可以把各种资源包括.png、.jpg、.qss等添加到.qrc,主要有两种方式,第一种是直接双击.qrc使用默认的打开方式Qt Resource Editor打开,
Qt、C++动态UI_第11张图片
或者通过Qt Designer打开.ui进入资源浏览器添加,
Qt、C++动态UI_第12张图片

2、内嵌资源

通过上述方式创建.qrc并添加到项目、添加资源到.qrc,项目正式编译开始后,Qt会将.qrc编译成.cpp,然后再编译、链接进exe,

1>rcc QtWidgetsApplication1.qrc
1>qrc_QtWidgetsApplication1.cpp

直接打开qrc_MainApplication.cpp可以看到,

/****************************************************************************
** Resource object code
**
** Created by: The Resource Compiler for Qt version 5.12.12
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

static const unsigned char qt_resource_data[] = {
  // E:/work src/10 ??/7?QUiLoader/QtWidgetsApplication1/QtWidgetsApplication1/src/qt.png
  0x0,0x0,0xb,0xaf,
  0x89,
  0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,
  0x0,0x0,0x40,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0xaa,0x69,0x71,0xde,
  0x0,0x0,0x0,0x4,0x73,0x42,0x49,0x54,0x8,0x8,0x8,0x8,0x7c,0x8,0x64,0x88,
  0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0xff,
  0x1,0x9d,0x85,0x40,0x1a,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,
  0x74,0x77,0x61,0x72,0x65,0x0,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b,0x73,0x63,0x61,
  0x70,0x65,0x2e,0x6f,0x72,0x67,0x9b,0xee,0x3c,0x1a,0x0,0x0,0xb,0x2c,0x49,0x44,
  0x41,0x54,0x78,0x9c,0xe5,0x5b,0x7b,0x70,0x54,0xd5,0x1d,0xfe,0xee,0xbe,0xb3,0x9b,
  0xcd,0x3b,0x24,0x21,0x8f,0xd,0x24,0xc6,0x0,0x21,0x1,0x2a,0x2f,0x9,0x4,0x14,
  0x4a,0x83,0xf8,0xb6,0x3e,0x28,0x76,0xd4,0x8e,0x3a,0xad,0xb5,0x63,0x8b,0xda,0x6a,
  0xdb,0x91,0x47,0xb5,0x5a,0x3b,0xd3,0xa1,0xce,0x14,0xc7,0x7,0xb6,0xbe,0x46,0x19,
  0xea,0xb,0x14,0x21,0x12,0x85,0x90,0x18,0xc,0x20,0x9,0x9,0x79,0x1,0x9,0x98,
  0x90,0x90,0x84,0xbc,0x76,0xef,0xde,0xe7,0xb9,0xa7,0x7f,0x6c,0x12,0x89,0x7b,0xef,
  0x66,0xc3,0xde,0x8d,0x71,0xfa,0xcd,0x30,0xc3,0x39,0xbf,0x6f,0xcf,0xf9,0xdd,0x2f,
  0xe7,0x9c,0x7b,0xce,0xef,0xfc,0x2e,0x43,0x29,0xc5,0x58,0x70,0x16,0xbb,0xac,0x0,
  0xa,0x1,0xac,0x6,0x30,0xdb,0x68,0x62,0xe2,0x67,0x14,0x38,0x5c,0xc9,0x69,0x96,
  0x18,0x93,0x89,0x31,0x99,0xcc,0xc,0x65,0x18,0x86,0xf0,0x5e,0xd2,0xcb,0xf3,0x4a,
  0x8b,0xc8,0xd3,0x6a,0x49,0x52,0xca,0x65,0x89,0x7e,0x5a,0xbe,0xb9,0xae,0x67,0xcc,
  0xe,0xbe,0x47,0x30,0x63,0x9,0xe0,0x2c,0x76,0xdd,0xc,0x60,0x3b,0x80,0x18,0x0,
  0x70,0x65,0xdb,0x30,0x67,0xa1,0x13,0xe,0xa7,0x31,0xa8,0xe,0xbc,0x1e,0x22,0x7b,
  0x59,0xa5,0x8f,0xf7,0x92,0x56,0x51,0xa0,0x27,0x44,0x51,0x29,0x97,0x25,0xba,0xb7,
  0x7c,0x73,0x5d,0x7b,0xa8,0xce,0xeb,0x81,0x80,0x2,0x38,0x8b,0x5d,0xcf,0x2,0xf8,
  0xfd,0x70,0x39,0x7d,0x9a,0xd,0x4b,0x57,0xc7,0xe8,0xd2,0x31,0xe7,0x55,0x88,0xd7,
  0x43,0xfa,0x79,0xaf,0x72,0x4e,0x10,0x94,0x5a,0x49,0xa4,0x15,0xb2,0xa4,0xec,0x3d,
  0xb4,0xa9,0xae,0x45,0x97,0xe,0x82,0x84,0xa6,0x0,0xce,0x62,0xd7,0x75,0x0,0x76,
  0xf,0x97,0x1d,0x4e,0x23,0x8a,0x6f,0x8b,0x87,0xc5,0x6a,0x8,0xab,0x43,0x3c,0xa7,
  0x28,0x5e,0xf,0x19,0xe0,0xbc,0x4a,0x9b,0x28,0x28,0x27,0x45,0x81,0x56,0xca,0x12,
  0xdd,0x77,0x68,0x53,0xed,0xc9,0x70,0xf4,0xa7,0x2a,0x80,0xb3,0xd8,0x65,0x6,0x50,
  0xb,0x20,0x67,0xb8,0x6e,0xf9,0x9a,0x58,0x4c,0xcd,0xb0,0x86,0xc3,0x87,0xa0,0x20,
  0xa,0xa,0x65,0xdd,0x64,0x90,0xf3,0x2a,0xed,0x2,0xaf,0x34,0x48,0x22,0x3d,0x2c,
  0x49,0xb4,0xe4,0xd0,0xc6,0xda,0xaf,0x43,0x69,0x57,0x4b,0x80,0x1b,0x0,0x7c,0x38,
  0x42,0x62,0x80,0x9f,0xde,0x97,0x4,0x93,0x99,0x9,0xa5,0xaf,0xb0,0x40,0x12,0x29,
  0x65,0xdd,0xc4,0xc3,0x79,0x49,0x87,0xc0,0x2b,0xd,0xa2,0x48,0xab,0x64,0x91,0x96,
  0x12,0x42,0x2b,0x2b,0xb6,0xd4,0x29,0x63,0xfd,0x5e,0x4b,0x80,0x3f,0x2,0xf8,0xcb,
  0x70,0x39,0x2a,0xc6,0x84,0xb5,0x77,0x26,0xe8,0xeb,0x79,0x98,0x21,0x4b,0x94,0xb2,
  0x6e,0xe2,0xe5,0xbc,0x4a,0xa7,0xc0,0x2b,0x4d,0x5e,0xf,0xf9,0xe7,0xc1,0xa7,0x6a,
  0x3f,0xfd,0x2e,0xcf,0xa4,0xf1,0xfb,0xd9,0x97,0x16,0x62,0x13,0xb4,0x68,0x93,0x17,
  0x26,0x33,0xc3,0x44,0xc7,0x99,0x1c,0xd1,0x71,0xc8,0x2,0x90,0xd5,0xda,0xcc,0x9,
  0x0,0xfc,0x4,0xd0,0x5a,0xd1,0x32,0x2e,0x2d,0x44,0xd8,0x83,0x7b,0xe5,0xfd,0x10,
  0xa1,0x25,0x40,0x78,0x97,0xfa,0x49,0x84,0xff,0x9b,0x7,0xd5,0xc2,0x84,0x8,0x20,
  0xa,0xa,0x6,0xfb,0x9,0x8c,0xb2,0x13,0x89,0xf6,0x34,0x44,0x5a,0xf4,0xd9,0x4c,
  0xe9,0x81,0xb0,0xac,0x6e,0x94,0x52,0x9c,0x3d,0x25,0xe0,0x9b,0x33,0x2,0x32,0xa7,
  0x4c,0xc3,0xed,0x45,0xb7,0xe2,0xf6,0x25,0xeb,0x60,0xb7,0xd8,0x47,0x38,0xac,0x38,
  0x80,0xd6,0xfe,0x93,0xa8,0xef,0xae,0x42,0x59,0xeb,0xfb,0xe0,0x65,0x6f,0x38,0x5c,
  0x19,0x13,0xba,0xb,0x30,0xd8,0x4f,0xf0,0xe5,0xe7,0xfd,0x30,0xc3,0x8a,0x17,0x1f,
  0xdd,0x8a,0x6b,0xf3,0x56,0xab,0xf2,0x1c,0x96,0x68,0xcc,0x9a,0xb2,0x18,0xb3,0xa6,
  0x2c,0xc6,0x9a,0x9c,0x7b,0xf1,0x69,0xf3,0xeb,0xd8,0xd7,0xfc,0x6,0x28,0xc6,0x3e,
  0x9c,0xe9,0x9,0x5d,0x5,0x70,0xf7,0xcb,0x28,0xf9,0xa0,0x17,0xb1,0xd1,0x76,0x1c,
  0x7e,0xe1,0x0,0xe2,0x9c,0xc1,0xed,0x1d,0xec,0x66,0x27,0x6e,0x99,0xf9,0x10,0xa6,
  0xc7,0xe6,0x61,0xfb,0xb1,0xa7,0x20,0xc8,0x9c,0x3f,0x89,0x2,0x3b,0xff,0xdd,0x5,
  0xa3,0x91,0xc1,0xb9,0x77,0x6b,0xd1,0xcf,0x77,0xa1,0x9f,0xeb,0xc6,0xa1,0xb3,0x1f,
  0xa2,0xaa,0xbd,0xe4,0xb2,0x7d,0xd6,0x6d,0xd,0x90,0x25,0x8a,0xd2,0x4f,0xfa,0xc0,
  0x30,0x6,0xec,0x79,0xee,0xfd,0xa0,0x1f,0xfe,0x52,0xcc,0x49,0x29,0xc2,0x3,0x57,
  0x3d,0x3,0x6,0xfe,0x3b,0xce,0x81,0x3e,0x19,0xa2,0xa0,0x20,0x7b,0xda,0x54,0xd8,
  0x4c,0x76,0x24,0x47,0x66,0x22,0x37,0x71,0x3e,0xd2,0xa3,0x73,0x54,0x5a,0xa,0x1e,
  0xba,0x9,0x50,0xf7,0x35,0xb,0x76,0x90,0xe0,0x9e,0x1b,0x6e,0x40,0x76,0x92,0xb6,
  0x53,0xcd,0x17,0x4e,0x62,0xc3,0xf6,0x47,0x50,0xd9,0x7c,0x48,0xd5,0x9e,0x97,0x74,
  0x35,0x56,0x65,0xaf,0xf3,0xab,0xef,0xee,0x14,0x1,0x0,0xf3,0x73,0xe7,0xe8,0xe3,
  0xf0,0x10,0x74,0x11,0xc0,0xcb,0x12,0x34,0x56,0xb3,0x88,0x8d,0x8d,0xc0,0xd3,0xeb,
  0x9f,0xd5,0xe4,0x7d,0xd4,0xf0,0x12,0xfe,0x5e,0x79,0x2f,0x1a,0xdd,0x9f,0xa3,0x78,
  0xc3,0x7a,0x2c,0xff,0xc3,0x72,0x28,0xd4,0x7f,0xbb,0x7e,0x7d,0xee,0x3,0xb0,0x9a,
  0x22,0x46,0xd5,0x75,0x75,0xf8,0x4,0x58,0x3d,0x4f,0x7d,0x4d,0xb9,0x5c,0xe8,0x22,
  0xc0,0xe9,0x7a,0xe,0x32,0xa1,0xb8,0xe5,0xda,0x55,0xb0,0x98,0xd4,0x4f,0x8c,0xd,
  0x3d,0x47,0xf0,0x49,0xd3,0x6b,0x0,0x80,0xd4,0x4c,0x1b,0xf2,0xe6,0x3a,0x70,0xb4,
  0xba,0x5,0x4f,0xbd,0xfd,0xa4,0x1f,0xd7,0x62,0xb4,0x61,0x6e,0xca,0x8a,0x51,0x75,
  0xdd,0x9d,0x22,0xcc,0x66,0x6,0xab,0xa,0x7e,0xa2,0x87,0xcb,0x23,0xd0,0x45,0x80,
  0x6f,0xce,0x8,0x0,0x80,0xfb,0x7f,0x7c,0xbf,0x26,0xe7,0x40,0xcb,0x7f,0x41,0x2f,
  0xf9,0x6b,0x5f,0x59,0x10,0x89,0x8,0xbb,0x1,0xdb,0x76,0xee,0xc0,0x20,0x37,0xe0,
  0xc7,0x5f,0x98,0xf6,0xed,0x83,0xb2,0x1e,0x2,0xd6,0xad,0x20,0x33,0x3d,0x11,0x66,
  0xa3,0x59,0xf,0x97,0x47,0x10,0xb2,0x0,0x9e,0x1,0x19,0xfd,0xbd,0x12,0x52,0x92,
  0x9d,0x98,0x95,0x9e,0xaf,0xc9,0x3b,0xd3,0x5b,0x33,0xaa,0x6c,0x34,0x2,0xf1,0x49,
  0x66,0x8,0x3c,0x41,0x49,0xf5,0x1e,0x3f,0x7e,0x6e,0xe2,0x7c,0xb4,0xd4,0x58,0xf0,
  0xee,0xcb,0x9d,0x58,0x99,0xfa,0x20,0x2a,0x5f,0xda,0x85,0x77,0xfe,0xf4,0x86,0x1f,
  0x2f,0x23,0x26,0x17,0x8b,0xd2,0xd7,0x20,0x3f,0xb9,0x10,0x59,0x71,0xf9,0x70,0x5a,
  0x63,0xc7,0xe5,0x7f,0xc8,0xaf,0xc1,0xee,0x4e,0x9,0x0,0x90,0x77,0x45,0xb6,0x26,
  0xa7,0x97,0xeb,0x44,0x3f,0xef,0x1f,0x1b,0x8d,0x4f,0x34,0xa3,0xad,0x45,0xc0,0x81,
  0xda,0x83,0xb8,0x75,0xd1,0x9d,0xa3,0x6c,0x6,0xc6,0x80,0xb5,0x57,0xad,0xc5,0x97,
  0x15,0xff,0x82,0xd5,0x68,0xd3,0x14,0x77,0x46,0xe2,0x2,0xcc,0x48,0x5c,0x30,0x52,
  0xde,0xdd,0xf8,0xa,0x76,0x35,0xbc,0x1c,0xb4,0xff,0x21,0x8f,0x0,0x8e,0x25,0x0,
  0x80,0xe4,0xd8,0x29,0x9a,0x9c,0x33,0xbd,0xb5,0xaa,0xf5,0x71,0x53,0x7c,0xc3,0xf9,
  0x78,0x53,0x9d,0xaa,0x7d,0xf9,0xec,0x15,0xaa,0xf5,0x7a,0x22,0x74,0x1,0xbc,0xbe,
  0x79,0x9d,0x92,0x30,0x55,0x93,0x33,0x20,0x5c,0x54,0xad,0x8f,0x89,0xf5,0xd,0xc0,
  0x73,0xe7,0x2f,0xa8,0xda,0x13,0xa3,0x92,0x42,0xf4,0x6e,0x6c,0x84,0x3c,0x5,0x86,
  0x5,0xc8,0x48,0x4c,0xd3,0xe4,0x88,0x6a,0x3b,0x3b,0x0,0x16,0x8b,0x4f,0x7f,0x41,
  0x90,0x55,0xed,0xd1,0x11,0x71,0x58,0x75,0x63,0x1c,0xb6,0xee,0xda,0x8a,0x67,0xde,
  0xfc,0x7,0xde,0xfd,0xf3,0x7f,0x30,0x33,0x6d,0x54,0xac,0x6,0x8d,0x5d,0xc7,0xd1,
  0xd8,0x75,0x1c,0x16,0xa3,0x15,0x76,0x6b,0x24,0xce,0xf,0x8e,0x2f,0xa8,0xac,0x9b,
  0x0,0xae,0x84,0x4c,0x4d,0x8e,0x40,0xd4,0x5,0x30,0x9a,0x18,0x80,0x1,0x24,0x59,
  0x3d,0x74,0x67,0x37,0x3b,0x91,0x9c,0x6a,0x47,0x7d,0x4d,0xf,0xda,0xce,0xf1,0x18,
  0x60,0xfb,0xfd,0x38,0xad,0x3,0x35,0xf8,0xf8,0xf4,0xb6,0xf1,0x3b,0x3e,0x4,0x1d,
  0xa6,0x80,0x6f,0xd,0xc8,0x4e,0xbe,0x42,0x93,0xa3,0x35,0x2,0xc0,0x0,0x26,0x93,
  0x1,0xb2,0xa4,0x1d,0xbb,0x74,0x5a,0xc6,0xb7,0xaa,0x8f,0x17,0xa1,0xb,0xc0,0x29,
  0x30,0x18,0x80,0xa9,0xf1,0xe9,0x9a,0x1c,0x81,0xf0,0x9a,0x36,0xb3,0x19,0x20,0x84,
  0x42,0x22,0x92,0xaa,0xdd,0x69,0x8d,0xb,0xd5,0xc5,0x80,0x8,0x49,0x0,0x59,0xa2,
  0x20,0x12,0x85,0xc3,0x61,0x81,0x81,0xd1,0x6e,0x4a,0x6b,0xa,0x0,0x43,0xd3,0x0,
  0xc0,0x80,0xd7,0x7f,0x33,0x4,0x0,0x51,0xe3,0x7c,0xaf,0x8f,0x17,0x21,0x9,0x20,
  0x49,0xbe,0xb3,0xbb,0xd9,0x1c,0x38,0x68,0x2a,0x6b,0xfc,0x75,0x1,0xdf,0x14,0x0,
  0x0,0xf,0xaf,0x2e,0x80,0xc3,0x12,0x7d,0x99,0xde,0x5,0x87,0x90,0x4,0x18,0xbe,
  0x26,0xe3,0x79,0xed,0x7,0x4,0x0,0x8b,0xc9,0xa6,0x69,0x23,0x8a,0x4f,0x44,0x87,
  0xd5,0xa9,0x6a,0x17,0x3,0x4c,0x1f,0x3d,0x10,0x92,0x0,0x46,0x23,0x60,0x32,0x1b,
  0xc0,0xf3,0xea,0xaf,0xb1,0x61,0x58,0x8d,0x1,0x4,0x18,0x1a,0x45,0x4e,0x5b,0x94,
  0xaa,0x9d,0x15,0x7,0x2f,0xdf,0xc1,0x20,0x10,0xf2,0x22,0x68,0xb5,0x31,0x50,0x14,
  0xa0,0xc7,0xad,0x9d,0x6,0x60,0x31,0x46,0x68,0xda,0x24,0x49,0x81,0xc1,0xc0,0xc0,
  0x66,0x51,0x17,0x89,0x95,0x26,0xb9,0x0,0x36,0x9b,0xaf,0x89,0xf6,0xde,0x36,0x4d,
  0xce,0x77,0xcf,0xf6,0x97,0x82,0xc8,0x14,0xc6,0x0,0x4b,0x88,0x77,0xd2,0x8f,0x80,
  0x8,0x5f,0x13,0x1d,0x7d,0xda,0xf9,0xe,0x16,0xa3,0x7a,0x8c,0x40,0x51,0x7c,0xff,
  0x4c,0x16,0x6d,0x37,0x26,0xfd,0x8,0xb0,0x5a,0x7d,0xaf,0xb1,0xce,0xbe,0xe,0x6d,
  0x8e,0xc6,0x14,0x20,0xb2,0x6f,0xfe,0x9b,0x34,0x86,0x80,0xa4,0x88,0x90,0x88,0x10,
  0xa2,0x87,0x81,0xa1,0xc3,0x1a,0xe0,0x73,0xfe,0x42,0xbf,0xfa,0x81,0x6,0x0,0xe2,
  0xed,0x29,0xaa,0xf5,0x2,0xe7,0xdb,0x45,0x46,0xda,0xd5,0x47,0x48,0x1f,0xd7,0x15,
  0xa2,0x77,0x63,0x23,0x64,0x1,0xe2,0x92,0x7c,0xc7,0x89,0xc3,0xf5,0x55,0x9a,0x9c,
  0x8c,0x98,0x5c,0xd5,0xfa,0xde,0x1e,0xdf,0xdb,0x23,0x2b,0x5d,0xfd,0x20,0xd5,0xd4,
  0x73,0x34,0x44,0xef,0xc6,0x46,0xc8,0x2,0xa4,0x66,0xd8,0x60,0x30,0x0,0x95,0xd5,
  0xea,0x67,0x7a,0x0,0x88,0xb1,0x25,0xaa,0x46,0x6a,0x7a,0x7b,0x7c,0xfb,0x87,0x82,
  0xec,0x59,0xaa,0xbf,0xab,0xef,0xfe,0x6a,0xcc,0xfe,0x99,0x0,0x3b,0xd0,0x60,0x10,
  0xb2,0x0,0x66,0xb,0x83,0xa4,0x54,0x2b,0xdc,0x83,0x22,0xf6,0xd5,0xf8,0x87,0xb6,
  0x86,0x91,0x11,0xed,0x3f,0xa,0xfa,0x86,0x46,0x40,0xe1,0xac,0xa5,0x7e,0x36,0xa,
  0x8a,0x86,0xee,0x23,0xc3,0x85,0x91,0xba,0xef,0x22,0xc1,0x9e,0x7a,0x19,0x5e,0x7f,
  0xb,0x5d,0x82,0xa2,0xa9,0x2e,0xdf,0x1c,0x7e,0x6b,0xff,0x5b,0x9a,0x9c,0xfc,0xe4,
  0xc2,0x51,0x65,0x59,0xa2,0xe8,0xb9,0x20,0x22,0xc2,0x61,0xc4,0x8a,0xbc,0x95,0x7e,
  0xfc,0xb6,0x81,0x26,0x78,0x44,0xdf,0xf1,0xd7,0x3c,0xb4,0xd0,0x76,0xd,0x76,0xfb,
  0xf7,0x1d,0x35,0x1d,0x0,0x20,0x89,0x14,0x7d,0x17,0x65,0x18,0x88,0xdd,0x8f,0x13,
  0x8,0xfa,0x8,0x90,0xe9,0x13,0xa0,0xec,0xeb,0x63,0x9a,0x9c,0x65,0x99,0x37,0x63,
  0xaa,0x73,0xfa,0x48,0xf9,0xc4,0x51,0xf,0x24,0x91,0xe2,0xf1,0xf5,0xf7,0xc3,0x61,
  0x8d,0xf4,0xe3,0x1f,0xef,0x38,0x38,0xf2,0xff,0xc8,0xa1,0x9c,0xc4,0xe6,0xf6,0x46,
  0x3f,0x5e,0x52,0xa4,0xb,0xeb,0xae,0xdc,0x88,0x14,0x71,0x39,0x7e,0x57,0xb8,0x15,
  0x8f,0xad,0x78,0x61,0x5c,0xbe,0xeb,0x22,0x80,0x23,0xd2,0x88,0xe4,0x54,0xb,0xba,
  0xbb,0x59,0x7c,0x72,0x6c,0x97,0x7a,0x47,0x8c,0x11,0x77,0xcf,0x79,0x12,0x53,0x1c,
  0x69,0x68,0xae,0xf3,0xe2,0x54,0x3d,0x87,0xd5,0xcb,0x7e,0x84,0x47,0x6f,0x7a,0xc2,
  0x8f,0xdb,0xcd,0xb6,0x61,0xef,0xa9,0x6f,0x23,0xc0,0xce,0x68,0xdf,0x42,0xdb,0x70,
  0xae,0x49,0xb5,0xed,0xa2,0xdc,0x62,0x3c,0xfd,0xb3,0xbf,0x61,0x51,0x4e,0xa1,0xea,
  0xb5,0x5a,0x20,0xe8,0x76,0x35,0xb6,0xf8,0x9a,0x68,0xd8,0x22,0xc,0x78,0xe0,0xf9,
  0xd,0xe8,0xea,0xef,0x54,0xe5,0x4c,0x8f,0x9b,0x8d,0x27,0x97,0xbd,0x85,0x9f,0x2f,
  0xfa,0x2d,0x4e,0xbc,0x7a,0x10,0x3b,0x9f,0x78,0xcf,0x8f,0x43,0x41,0xf1,0xfa,0xf1,
  0xa7,0x47,0xbd,0xff,0x33,0xb2,0x6c,0x70,0x38,0xd,0xd8,0x7d,0xb0,0x4c,0xf5,0xe,
  0x21,0x14,0xe8,0x26,0x40,0x84,0xc3,0x88,0x25,0x2b,0x63,0x30,0x38,0x20,0xe2,0xfa,
  0x4d,0xb7,0xa8,0x5e,0x79,0x1,0x40,0x84,0xc5,0x86,0x7b,0xae,0xb9,0xf,0xa9,0x1a,
  0x1,0x94,0xb2,0xd6,0xf,0xd0,0xd4,0x33,0x7a,0x2a,0x19,0xc,0xc0,0xfc,0x65,0x31,
  0x90,0x24,0x82,0x3b,0x9f,0xbb,0xb,0x5e,0xd1,0x3f,0x97,0x80,0x97,0x59,0x54,0x77,
  0x1e,0xc4,0xfe,0x33,0xef,0x8c,0xcb,0x6f,0x5d,0xaf,0xc7,0x93,0x52,0x2d,0x28,0x58,
  0x10,0x89,0xe3,0x87,0xdb,0xf1,0xd0,0x8b,0xf,0x62,0xdb,0x2f,0x83,0x8f,0xcf,0x53,
  0x50,0x94,0x9f,0xfd,0x8,0x3b,0xeb,0xb6,0xaa,0xda,0xa7,0xa6,0x5b,0x70,0xdd,0x1d,
  0x9,0x68,0x6b,0xf9,0x6,0xeb,0x5e,0x58,0x83,0xa2,0x82,0xa5,0xc8,0x9f,0x56,0x0,
  0xaf,0xd4,0x87,0xfa,0xee,0x2a,0xb4,0xf4,0xd5,0x42,0xa1,0x64,0xdc,0x3e,0xeb,0x9e,
  0x20,0x31,0x73,0xae,0x3,0x56,0x9b,0x1,0x3b,0xf6,0x7e,0x86,0xb,0x7d,0x37,0x61,
  0xfb,0x23,0xaf,0x21,0xc6,0x1e,0x38,0xaa,0xd3,0xe1,0x6e,0xc1,0x9b,0xd5,0x7f,0xc5,
  0xa9,0x8b,0xd5,0x1,0x79,0x76,0x87,0x11,0x39,0x79,0x76,0x0,0x1c,0x1a,0xd8,0x7d,
  0x68,0xa8,0xdd,0x17,0xb2,0xbf,0x61,0x49,0x91,0xc9,0x9a,0x11,0x81,0xb4,0x69,0x56,
  0xb4,0x9e,0x3a,0x8d,0x65,0x8f,0x17,0x21,0x37,0x3d,0x7,0xbf,0xb9,0xf1,0x61,0x14,
  0xe6,0x16,0xf9,0x71,0xfb,0xb8,0xb,0xd8,0xf2,0xc5,0x7a,0x10,0x25,0x70,0x4c,0x21,
  0x5c,0x8,0x5b,0x92,0x94,0xd5,0x66,0xc0,0x95,0x79,0x76,0xe4,0x2f,0xb4,0x60,0xcf,
  0x17,0x55,0xf8,0xc5,0xf3,0xf,0xab,0xf2,0x62,0x23,0x92,0x90,0x19,0xa3,0xbe,0x13,
  0xd4,0x15,0x1a,0xb9,0x37,0x61,0xcf,0x12,0x73,0x44,0x19,0x11,0x1b,0x6f,0xc2,0xf9,
  0x8e,0x1,0x9c,0x6c,0x3b,0xa1,0xca,0x59,0x99,0x75,0x57,0xb8,0xdd,0x80,0x2c,0xd3,
  0x33,0x6a,0xf5,0x13,0x92,0x26,0x97,0x36,0xcd,0x6,0x50,0xe0,0xd5,0x92,0x57,0x54,
  0xed,0x73,0x53,0x8a,0xb0,0x61,0xc9,0x36,0xac,0xca,0xba,0x1b,0x57,0xc4,0xcf,0xb,
  0x8b,0xf,0x92,0x44,0x55,0x53,0x52,0x26,0x44,0x0,0x57,0x56,0x4,0xc,0x6,0x60,
  0x77,0x59,0xa9,0xea,0x5c,0x67,0x18,0x3,0x72,0x12,0xe6,0xe1,0xb6,0xbc,0x5f,0x63,
  0x89,0x6b,0xad,0xee,0xfd,0x13,0x99,0x82,0xc8,0xb4,0x54,0xcd,0x36,0x21,0x2,0x44,
  0xc5,0x1a,0x51,0xb0,0xc0,0x89,0xf3,0x1d,0x83,0xf8,0xd5,0x8b,0xf,0x4e,0x44,0x97,
  0xa3,0xd0,0xd9,0x2e,0xd6,0x94,0x6f,0xae,0x53,0xd,0x2d,0x4d,0x58,0xaa,0xec,0x8c,
  0x2,0x7,0x52,0x5d,0x56,0xbc,0xf3,0xf1,0x7e,0xec,0xa8,0xd0,0x3e,0x34,0xe9,0xd,
  0xaa,0x0,0x3,0xbd,0xf2,0x43,0x5a,0xf6,0x89,0xcb,0x83,0x67,0x80,0xa2,0xe2,0x58,
  0xb4,0xb7,0xf2,0xd8,0xf4,0xf6,0x66,0x7c,0x58,0xf5,0x1e,0x16,0x66,0x2f,0xc1,0xe2,
  0xdc,0xc5,0xc8,0x4d,0xcb,0x5,0x2f,0xb3,0xe8,0xe3,0xba,0x70,0xfa,0x62,0xcd,0xd8,
  0x6d,0x8d,0x3,0x2d,0xcd,0xdc,0x1b,0x65,0x1b,0x6b,0xd5,0x53,0xd2,0xa0,0xfd,0xc1,
  0x44,0x25,0x80,0x85,0xc3,0xe5,0xdc,0x7c,0x7,0xe6,0x5d,0xad,0x7e,0x71,0x31,0x59,
  0xa1,0x28,0x14,0x67,0x4f,0xf1,0x3b,0xf6,0x3d,0x56,0x73,0x47,0x20,0xde,0xf,0xef,
  0x4b,0x88,0x0,0x90,0x25,0x4a,0x3d,0x6e,0xc2,0xe,0xf6,0xc9,0x47,0xdc,0x3,0xe4,
  0xe1,0x43,0x9b,0x6a,0xd5,0x53,0x53,0x2e,0xc1,0xf,0x52,0x0,0x59,0xa6,0x60,0x7,
  0x9,0xeb,0xf5,0x92,0xe,0x81,0xa3,0xd,0x92,0xa8,0x7c,0x25,0x89,0xb4,0xa4,0x6c,
  0x63,0x6d,0xe5,0x78,0xdb,0x9a,0xd4,0x2,0x10,0x99,0xc2,0xe3,0x26,0x5e,0x8e,0x55,
  0x3a,0x4,0x5e,0x69,0x14,0x5,0xa5,0x4a,0x12,0xe9,0x67,0x84,0xd0,0x8a,0x60,0x3e,
  0x88,0xa,0x6,0x5a,0x2,0x4c,0x68,0xca,0x36,0x21,0x14,0x9e,0x41,0xc2,0x71,0xac,
  0xef,0x3,0x27,0x51,0x50,0xaa,0x24,0x89,0x7e,0x46,0x64,0x5a,0x5e,0xb1,0xa5,0x2e,
  0xac,0x87,0x4,0x2d,0x1,0xfe,0x8,0xdf,0x67,0x73,0xfe,0xb1,0xaa,0x10,0xa0,0x10,
  0xa,0x8f,0x9b,0xf0,0x1c,0xab,0x74,0xf2,0x9c,0xd2,0x2c,0x8a,0xca,0x11,0x49,0xa4,
  0xfb,0x89,0x4c,0xf,0x84,0xfb,0x41,0xb5,0xa0,0x2a,0x80,0x7b,0xcf,0xd9,0x52,0x67,
  0xb1,0xeb,0x1a,0x0,0x7b,0x0,0xc4,0x8f,0xb7,0x51,0x45,0xa1,0x60,0xdd,0x84,0xf7,
  0xb2,0x4a,0x97,0xc0,0x29,0xa7,0x44,0x41,0x39,0x2a,0x89,0xb4,0x54,0x96,0x69,0x69,
  0xc5,0x96,0x3a,0x31,0x54,0xa7,0xf5,0x84,0xe6,0x1a,0xe0,0xde,0x73,0xb6,0xca,0x59,
  0xec,0x5a,0xa,0xa0,0x4,0x80,0x6a,0xec,0x59,0x51,0x0,0xd6,0x4d,0x4,0x8e,0x25,
  0xdd,0xfc,0xf0,0x83,0x4a,0xf4,0x73,0x59,0xa2,0xfb,0x2b,0xb6,0xd4,0x85,0xf7,0x62,
  0x5f,0x27,0x4,0xf3,0xf5,0xb8,0x6b,0xe6,0x1c,0x47,0x65,0xf6,0x4c,0x7b,0x9c,0xd7,
  0x43,0xba,0x79,0x5e,0x39,0x2d,0xa,0xca,0x31,0x49,0xa4,0x5f,0xc8,0x32,0x2d,0xa9,
  0xd8,0x5c,0xf7,0xfd,0x7c,0xeb,0xa2,0x13,0xfe,0x7,0x6a,0x59,0x8e,0x78,0x3b,0xce,
  0xc8,0xd8,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82,
  
};

static const unsigned char qt_resource_name[] = {
  // QtWidgetsApplication1
  0x0,0x15,
  0x1,0x6d,0xd9,0xd1,
  0x0,0x51,
  0x0,0x74,0x0,0x57,0x0,0x69,0x0,0x64,0x0,0x67,0x0,0x65,0x0,0x74,0x0,0x73,0x0,0x41,0x0,0x70,0x0,0x70,0x0,0x6c,0x0,0x69,0x0,0x63,0x0,0x61,0x0,0x74,
  0x0,0x69,0x0,0x6f,0x0,0x6e,0x0,0x31,
    // src
  0x0,0x3,
  0x0,0x0,0x7a,0x83,
  0x0,0x73,
  0x0,0x72,0x0,0x63,
    // qt.png
  0x0,0x6,
  0x7,0x87,0x57,0x47,
  0x0,0x71,
  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,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  // :/QtWidgetsApplication1
  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  // :/QtWidgetsApplication1/src
  0x0,0x0,0x0,0x30,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  // :/QtWidgetsApplication1/src/qt.png
  0x0,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
0x0,0x0,0x1,0x7d,0x27,0x7a,0x82,0x80,

};

#ifdef QT_NAMESPACE
#  define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
#  define QT_RCC_MANGLE_NAMESPACE0(x) x
#  define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
#  define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
#  define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
        QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
#else
#   define QT_RCC_PREPEND_NAMESPACE(name) name
#   define QT_RCC_MANGLE_NAMESPACE(name) name
#endif

#ifdef QT_NAMESPACE
namespace QT_NAMESPACE {
#endif

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

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

#ifdef QT_NAMESPACE
}
#endif

int QT_RCC_MANGLE_NAMESPACE(qInitResources_QtWidgetsApplication1)();
int QT_RCC_MANGLE_NAMESPACE(qInitResources_QtWidgetsApplication1)()
{
    QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
        (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtWidgetsApplication1)();
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtWidgetsApplication1)()
{
    QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
       (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

namespace {
   struct initializer {
       initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_QtWidgetsApplication1)(); }
       ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_QtWidgetsApplication1)(); }
   } dummy;
}

添加到.qrc的资源被转成了16进制数组。关于Qt的rcc,简单介绍下,

rcc工具主要用于处理资源文件,可以将资源文件(如图片、音频、视频等)打包成二进制文件(*.rcc),以便于在程序中加载和使用。rcc工具主要有以下两种用途:

  1. 生成独立的二进制资源文件:对于较大的资源文件,不适合直接集成到目标程序内部,可以将其放到操作系统文件路径,或单独编译成外挂资源文件(*.rcc)。rcc工具可以将资源文件压缩打包,生成一个二进制的*.rcc文件,其中包含了所有的资源文件。这样,在程序发布时,只需要带一个*.rcc文件即可,而不必带一堆乱七八糟的碎文件。
  2. 应用程序内嵌资源:可以将资源文件编译到应用程序内部,作为内嵌资源。这在需要频繁使用某些资源文件时可以提高程序的启动速度和运行效率。在Qt应用程序中,可以通过包含相应的*.rcc文件来访问内嵌资源。

因此,一般将.qrc添加到项目中编译、链接进exe只是rcc的一种用法,即应用程序内嵌资源。而应用程序内嵌资源通常会使得exe本身体积增大,对于有些较大且非经常使用到的的资源则不太合适。接下来介绍下如何生成独立的二进制资源文件。

3、外挂资源

利用rcc工具,将.qrc单独编译成外挂资源文件(*.rcc),可以把资源从exe剥离出来,方便替换而不用编译代码。

rcc工具具体指Qt提供的一个程序rcc.exe,比如本文所用Qt5.12.12在如下目录:
在这里插入图片描述
实现方式也简单,只需要把xxx.qrc文件编译成xxx.rcc文件,然后在程序启动时加载.rcc文件,后面的调用方式便和第一种方式一样了,具体命令如下:

 rcc --binary resource.qrc -o resource.rcc

加载rcc:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    if(QResource::registerResource( R"(E:/work src/test/QtWidgetsApplication1/resource.rcc)") == true)
    {
        qDebug()<<"it's ok";
    }
    else
    {
        qDebug()<<"it's not ok";
    }
    MainWindow w;
    w.show();
    return a.exec();
}

小结下,使用.rcc文件的优点如下:

  • 节省内存空间;
  • 改变资源时,不需要再次编译程序,只需将旧的.rcc文件替换即可。

使用.rcc文件的步骤如下:

  1. 生成.qrc文件;

  2. .qrc及其所包括所有资源, 和 rcc.exe放在同一个目录下,或将rcc.exe配置到环境变量;
    在这里插入图片描述

  3. 使用下述命令,根据.qrc文件生成.rcc文件:

     rcc --binary resource.qrc -o resource.rcc
    
  4. 程序中添加 QResource::registerResource()加载.rcc文件。
    在不需要的时候使用QResource::unregisterResource()来进行注销,其余即像使用.qrc那样使用了。所以,我们可以把某业务的资源统一由指定的.qrc管理,加载资源前先加载.qrc

有了resource.rcc后,图标资源就可以不需要了,因为都已经编进里面了。

另外,可以通过QResource::unregisterResource从程序中卸载.rcc文件。不过,如果程序已经加载了图标资源,那么此时卸载.rcc并不会影响已加载的图标,而只会导致后续加载图标失效。

同理,如果程序中使用图标资源是在加载对应.rcc之前,图标加载也不会因为QResource::unregisterResource()而立即生效。不过,如果是通过样式表(qss)来设置图标的,可以使用下面的方法来立即刷新,

ui.label->setStyleSheet(ui.label->styleSheet());
style()->polish(ui.label);

五、小结

通过本文前序章节的介绍,我们已经走通了QUiLoader加载.ui、插件(自定义控件)、外挂资源文件。为方便管理,我们可以修改插件项目输出路径,保证.ui、.dll、.rcc处于同一目录下:

Qt、C++动态UI_第13张图片
完全加载代码如下:

QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
    : QMainWindow(parent)
{
    const QString runtimeUIPath = R"(E:/work src/test/QtWidgetsApplication1/src_runtime/)";
    QResource::registerResource(runtimeUIPath + "resource.rcc");

    QUiLoader loader;
    loader.addPluginPath(runtimeUIPath);
    QFile file(runtimeUIPath + "Widget.ui");
    file.open(QFile::ReadOnly);
    QWidget *myWidget = loader.load(&file, this);
    file.close();

    auto *layout = new QVBoxLayout;
    layout->addWidget(myWidget);
    
    ui.setupUi(this);
    ui.centralWidget->setLayout(layout);
}

你可能感兴趣的:(ui,qt,c++)