Qt QResource 配合 rcc 命令,资源文件与源码分离,可以挂载多个资源,存在优先级,先加进去 de 先检索到。
使用 rcc 命令将 resource.qrc 生成 .rcc 二进制文件。
rcc --binary resource.qrc -o skin.rcc # Windows
rcc -binary resource.qrc -o skin.rcc # Linux
QResource::registerResource(qApp->applicationDirPath() + "/skin/skin.rcc");
QFile file(":/qss/stylesheet");
if (file.open(QFile::ReadOnly))
{
QString strStyleSheet = file.readAll();
file.close();
qApp->setStyleSheet(strStyleSheet);
}
QResource::unregisterResource();
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;
}
编译成静态 lib,就需要自己调用一下;编译成动态 dll,就自动被调用了。
fastvceng::initResources(bDebug);
fastvcwidget::initResources(bDebug);
#pragma once
#include <QtCore/qglobal.h>
#ifndef FASTVCWIDGET_STATIC
# if defined(FASTVCWIDGET_LIB)
# define FASTVCWIDGET_EXPORT Q_DECL_EXPORT
# else
# define FASTVCWIDGET_EXPORT Q_DECL_IMPORT
# endif
#else
# define FASTVCWIDGET_EXPORT
#endif
#pragma once
#include "fastvcwidget_global.h"
class FASTVCWIDGET_EXPORT fastvcwidget
{
public:
fastvcwidget();
static void initResources(bool debug);
static bool isDebug() { return m_debug; }
private:
static bool m_debug;
};
#include "fastvcwidget.h"
fastvcwidget::fastvcwidget()
{
}
bool fastvcwidget::m_debug = false;
void fastvcwidget::initResources(bool debug) {
m_debug = debug;
Q_INIT_RESOURCE(fastvcwidget);
}
namespace {
struct ResourceLoader {
public:
ResourceLoader() { fastvcwidget::initResources(
#ifdef _DEBUG
1
#else
0
#endif
); }
} fastvcwidget_ResourceLoader;
}
#include "qtest.h"
qtest::qtest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
// 都包含 ":/qtest/image.png"
Q_CLEANUP_RESOURCE(qtest_default);
Q_CLEANUP_RESOURCE(qtest_usen);
Q_CLEANUP_RESOURCE(qtest_zhcn);
// 多个图片素材包,先放进去的先检索到。
//Q_INIT_RESOURCE(qtest_zhcn); // 柠檬
Q_INIT_RESOURCE(qtest_usen); // 石头
Q_INIT_RESOURCE(qtest_default); // 橙子
QImage myImage;
bool temp = myImage.load(":/qtest/image.png");
ui.imageLabel->setPixmap(QPixmap::fromImage(myImage));
}
工程默认配置多个 qrc: resource.qrc,resource_usen.qrc,resource_zhcn.qrc。 根据国内版还是国外版,合理安排它们的顺序,就可以保证同样的路径,检索到不同的图片文件。
会生成多个源文件: rcc/qrc_resource.cpp、rcc/qrc_resource_usen.cpp、rcc/qrc_resource_zhcn.cpp。
void QMainClient::InitEnvironment() {
// 资源文件国际化
Q_CLEANUP_RESOURCE(resource);
Q_CLEANUP_RESOURCE(resource_usen);
Q_CLEANUP_RESOURCE(resource_zhcn);
// 多个图片素材包,先放进去的先检索到。
if (IsInternationEdition()) {
Q_INIT_RESOURCE(resource_usen);
Q_INIT_RESOURCE(resource);
} else {
Q_INIT_RESOURCE(resource_zhcn);
Q_INIT_RESOURCE(resource);
}
}
qrc_resource.cpp
qt_resource_data qt_resource_name qt_resource_struct
逆向破解分析 Hacking Tools 搜罗大集合(上) Hacking Tools 搜罗大集合(下)