【Qt】Qt换肤,使用QResource动态加载资源文件

【Qt】使用QResource动态加载资源文件

0.前言

对于简单的应用,我们可以直接读取 QSS 样式表文件来实现换肤。但一般样式里还带有图片等资源的路径,如果通过相对路径来加载,不便于管理,不过好处是替换图片方便。我们也可以使用 Qt 的 rcc.exe 工具将资源文件生成为二进制文件,在程序中使用 QResource 进行动态加载。

1.正文

Qt 资源系统是一种与平台无关的机制,用于在应用程序的可执行文件中存储二进制文件。如果你的应用程序始终需要一组特定的文件(图标,翻译文件等),这将很有用。

手动修改 qrc 的 xml 文件我感觉有点麻烦,还不如单独建个工程来管理不同皮肤的 qrc ,然后使用 rcc 生成为二进制资源文件(Win 下用 QtCreator 编译器对应的 Cmd,可以切换到 qrc 目录执行,rcc 还提供压缩功能详情见文档):

rcc -binary myresource.qrc -o myresource.rcc
rcc -binary myresource.qrc -o myresource.dll

然后在程序中调用静态函数动态加载:

QResource::registerResource("/path/to/myresource.rcc");
QResource::registerResource("/path/to/myresource.dll");

如果vs安装了qt-vsaddin-msvc2022*exe 插件,也可以右键qrc 文件设置 然后代码里面QResource::registerResource("/path/to/myresource.dll");
【Qt】Qt换肤,使用QResource动态加载资源文件_第1张图片

参考 Qt 文档(QResource ):https://doc.qt.io/qt-5/qresource.html

参考 Qt 文档(Qt 资源系统):https://doc.qt.io/qt-5/resources.html

2.实现

实现效果:
【Qt】Qt换肤,使用QResource动态加载资源文件_第2张图片
【Qt】Qt换肤,使用QResource动态加载资源文件_第3张图片

代码链接:

github 链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qt/QtSwitchSkin

主要代码(样式表和图片在资源文件中):

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include 
 
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
    void loadSkin(const QString &paths);
 
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
#include 
#include 
#include 
#include 
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    //为什么不用combobox?因为按钮样式更简单
    //可以在启动时读取目录下皮肤文件作为combobox的选项
    connect(ui->btnWhite,&QPushButton::clicked,this,[=](){
        loadSkin("white.rcc");
    });
    connect(ui->btnBlack,&QPushButton::clicked,this,[=](){
        loadSkin("black.rcc");
    });
    //加载默认样式
    loadSkin("white.rcc");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::loadSkin(const QString &paths)
{
    static QString old_paths;
    if(paths.isEmpty()||paths==old_paths)
        return;
 
    //先卸载当前的资源
    if(!old_paths.isEmpty()){
        const bool unresult=QResource::unregisterResource(old_paths);
        qDebug()<<"QResource::unregisterResource"<<unresult;
    }
    old_paths=paths;
 
    //加载资源文件
    const bool result=QResource::registerResource(paths);
    qDebug()<<"QResource::registerResource"<<result;
    if(result){
        //设置样式表
        QFile file(":/style.qss");
        if(file.open(QIODevice::ReadOnly)){
            const QString qss_str=file.readAll();
            qApp->setStyleSheet(qss_str);
        }
    }
}

你可能感兴趣的:(Qt,qt,数据库,开发语言)