QSS样式表实现界面换肤功能

2022-11-13 18:11:15 界面 样式表 换肤

前言

本篇,我们将对QSS样式表进行简单介绍,并且使用QSS样式表实现界面换肤功能。

一、实现效果

通过点击主界面的设置按钮,进入皮肤设置界面。选择想要设置的皮肤,并单击确定就能实现界面换肤。

在这里插入图片描述

二、QSS简介及用法

1.什么是QSS?

  • QSS是Qt Style Sheet的简称,也叫Qt样式表。在操作Qt制作软件界面的过程中,允许我们使用QSS自定义小部件的外观,以及通过子类化QStyle实现想要的功能界面。

2.怎么使用QSS?

  • QSS共有两种使用方法
  • 第一种是窗口内的单个控件直接调用setStyleSheet函数,将某个控件的外观进行自定义操作
  • 第二种是编写后缀为.qss文件,通过读取.qss文件的方式,批量更改窗口内所有或部分控件外观

三、QSS用法一:单个控件调用setStyleSheet函数

  • 友情提示:下拉至文章末尾可以查看样式表属性及其含义的链接
  • 调用语句:控件指针 -> setStyleSheet("控件类型{属性1:属性值;属性2:属性值;}");
  • 调用实例如下:
 //创建标签
    QLabel *title = new QLabel("iQIYI爱奇艺",this);
    //标签位置大小初始化
    title->setGeometry(250,265,180,50);
    //使用样式表自定义标签外观
    title->setStyleSheet("QLabel{font-size:30px;font-style:微软雅黑;font-weight:bold}");

以上案例实现了,将标签中的文字设置为:30px(字号),微软雅黑(字体),bold(加粗)

四、QSS用法二:编写单个界面.qss文件的并读取

1.创建qss文件

(1)在工程文件中,创建新建文本文档(记事本)、

在这里插入图片描述

(2)将新建文本文档后缀改为.qss

在这里插入图片描述

(3)以记事本打开的方式对.qss文件进行编辑

在这里插入图片描述

2. qss文件语法格式

  • 语法格式:选择器{属性1:属性值;属性2:属性值;}
  • 选择器类型如下表格:
类型实例含义
通配选择器*匹配所有控件
类型选择器QPushButton匹配所有QPushButton和其子类的实例
属性选择器QPushButton[flat="false"]匹配所有flat属性是false的QPushButton实例(可以是自定义属性,)
类选择器.QPushButton匹配所欲哦QPushButton的实例,但不匹配其子类,注意前面有一个点号
ID选择器#myButton匹配所有id为myButton的控件实例,这里的id需要用setObjectName函数设置
后代选择器QDialog QPushButton所有QDialog容器中包含的QPushButton(直接或间接)
子选择器QDialog > QPushButton所有QDialog容器下面的QPushButton(直接)

 

.qss文件实例

在这里插入图片描述

3.读取qss文件

我们可以在窗口中,以读入qss文件到字符串的方式,设置该窗口的QSS,具体代码如下。

void startWin::setQss(QString filename)
{
	//创建文件
    QFile file(filename);
    //只读方式打开文件
    file.open(QFile::ReadOnly);
    //将文件转换成文本流形式
    QTextStream filetext(&file);
    //将文本流中的所有字符存入新建字符串
    QString stylesheet = filetext.readAll();
    //设置该窗口的QSS
    this->setStyleSheet(stylesheet);
    //关闭文件
    file.close();
}

4.界面换肤

  • 提前创建好同一界面下,不同控件外观的qss文件,如下图所示。

在这里插入图片描述

以信号触发的方式进行换肤,下图为按钮单击信号触发的槽函数

void setWin::changeQssColor()
{
    //接收下拉框当前文本信息
    QString str = this->combo->currentText();

    //获取主界面
    startWin *start = startWin::getInstance();

    //根据下拉框信息,设置不同皮肤
    if(str == "天际蓝")
    {
        start->setQss("./qss/start1.qss");
    }
    else if(str == "低调灰")
    {
        start->setQss("./qss/start2.qss");
    }
    else if(str == "清新绿")
    {
        start->setQss("./qss/start3.qss");
    }
    else if(str == "活力紫")
    {
        start->setQss("./qss/start4.qss");
    }

    //关闭设置界面
    this->close();
}

五、完整源码

1.main.cpp文件

#include "widget.h"
#include <QApplication>
#include "startwin.h"

int main(int arGC, char *argv[])
{
    QApplication a(argc, argv);
    startWin *w = startWin::getInstance();
    w->show();
    return a.exec();
}

2.startwin.h文件

#ifndef STARTWIN_H
#define STARTWIN_H

#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QListWidget>
#include <QCloseEvent>

class startWin : public QWidget
{
    Q_OBJECT
private:
    explicit startWin(QWidget *parent = 0);
    static startWin *start;
public:
    static startWin *getInstance();
    QLabel *bg,*leftPic,*rightPic,*topPic;
    QLineEdit *edit1;
    QPushButton *newBtn1,*newBtn2,*newBtn3,*newBtn4,*newBtn5,*newBtn6,*newBtn7,*newBtn8;
    QVBoxLayout *leftLayout;
    QHBoxLayout *topLayout;
    QListWidget *videowins;
    QWidget *leftWin,*topWin;
    void closeEvent(QCloseEvent *event);
    void setQss(QString filename);
signals:

public slots:
    void settingSlot();
    void choseSolt();
};

#endif // STARTWIN_H

3.startwin.cpp文件

#include <QDir>
#include <QDebug>
#include <QPixmap>
#include <QStringList>
#include <QMessageBox>
#include "startwin.h"
#include "setwin.h"

startWin* startWin::start = nullptr;


startWin::startWin(QWidget *parent) : QWidget(parent)
{
    //设置主界面窗口大小
    this->setFixedSize(1200,747);

    //设置默认QSS
    this->setQss("./qss/start3.qss");

    //窗口背景图(白底)
    this->bg = new QLabel(this);
    this->bg->setGeometry(0,0,1200,747);
    this->bg->setPixmap(QPixmap("./picture/logic2.png"));
    this->bg->setScaledContents(true);

    //左窗口背景图
    this->leftPic = new QLabel(this);
    this->leftPic->setObjectName("leftPic");
    this->leftPic->setGeometry(0,0,181,747);

    //右上角图片
    this->rightPic = new QLabel(this);
    this->rightPic->setObjectName("rightPic");
    this->rightPic->setGeometry(655,0,545,70);

    //顶部图片传一log
    this->topPic = new QLabel(this);
    this->topPic->setGeometry(220,15,400,50);
    this->topPic->setPixmap(QPixmap("./picture/log.png"));
    this->topPic->setScaledContents(true);

    
    this->leftWin = new QWidget(this);
    this->leftWin->setGeometry(20,0,150,747);

    //创建垂直布局管理器
    this->leftLayout = new QVBoxLayout(leftWin);

    //压缩布局
    this->leftLayout->addStretch();

    //创建按钮内容链表
    QStringList leftList;
    leftList << "全部" << "电视剧" << "电影" << "综艺" << "儿童" << "动漫" << "游戏" << "纪录片" << "体育" << "知识" << "直播" << "随刻热点";

    //根据按钮链表内容生成按钮,并添加到垂直布局管理器
    for(int i=0;i<leftList.size();i++)
    {
        //新建按钮
        QPushButton *newBtn = new QPushButton(leftList.at(i));
        //设置按钮的objectname
        newBtn->setObjectName("newBtn");
        //将按钮添加到垂直布局管理器
        leftLayout->addWidget(newBtn);
        //设置各按钮之间的间隔
        leftLayout->addSpacing(16);
        //创建按钮槽函数
        connect(newBtn,SIGNAL(clicked(bool)),this,SLOT(choseSolt()));
    }
    //设置按钮与窗口底部的间隔
    leftLayout->addSpacing(10);

    
    this->topWin = new QWidget(this);
    this->topWin->setGeometry(181,0,1030,70);

    //创建水平布局管理器
    this->topLayout = new QHBoxLayout(topWin);
    this->topLayout->addStretch();

    //登录注册按钮
    this->newBtn6 = new QPushButton("登录");
    this->newBtn6->setFixedSize(50,30);
    this->topLayout->addWidget(newBtn6);
    this->topLayout->addSpacing(10);

    this->newBtn7 = new QPushButton("注册");
    this->newBtn7->setFixedSize(50,30);
    this->topLayout->addWidget(newBtn7);
    this->topLayout->addSpacing(10);

    this->newBtn8 = new QPushButton("个人中心",this);
    this->newBtn8->setGeometry(690,20,80,30);
    this->newBtn8->hide();

    //创建输入框
    this->edit1 = new QLineEdit();
    this->edit1->setFixedSize(150,30);
    this->topLayout->addWidget(edit1);
    this->topLayout->addSpacing(10);

    //创建搜索按钮,并添加到水平布局管理器
    this->newBtn1 = new QPushButton();
    this->newBtn1->setObjectName("newBtn1");
    this->newBtn1->setFixedSize(30,30);
    this->topLayout->addWidget(newBtn1);
    this->topLayout->addSpacing(10);

    //创建设置按钮,并添加到水平布局管理器
    this->newBtn2 = new QPushButton();
    this->newBtn2->setObjectName("newBtn2");
    this->newBtn2->setFixedSize(30,30);
    this->topLayout->addWidget(newBtn2);
    this->topLayout->addSpacing(10);
    connect(this->newBtn2,SIGNAL(clicked(bool)),this,SLOT(settingSlot()));

    //创建缩小按钮,并添加到水平布局管理器
    this->newBtn3 = new QPushButton();
    this->newBtn3->setObjectName("newBtn3");
    this->newBtn3->setFixedSize(30,30);
    this->topLayout->addWidget(newBtn3);
    this->topLayout->addSpacing(10);

    //创建放大按钮,并添加到水平布局管理器
    this->newBtn4 = new QPushButton();
    this->newBtn4->setObjectName("newBtn4");
    this->newBtn4->setFixedSize(30,30);
    this->topLayout->addWidget(newBtn4);
    this->topLayout->addSpacing(10);

    //创建关闭按钮,并添加到水平布局管理器
    this->newBtn5 = new QPushButton();
    this->newBtn5->setObjectName("newBtn5");
    this->newBtn5->setFixedSize(30,30);
    this->topLayout->addWidget(newBtn5);
    this->topLayout->addSpacing(10);

    //创建QListWidget窗口
    this->videowins = new QListWidget(this);
    this->videowins->setGeometry(181,90,1020,657);
    this->videowins->setViewMode(QListView::IconMode);
    this->videowins->setMovement(QListView::Static);
    this->videowins->setResizeMode(QListView::Adjust);
    this->videowins->setIconSize(QSize(1000,500));
    this->videowins->setSpacing(33);

    //存储每个文件夹路径
    QString paths[12] = {"./picture/btn12","./picture/btn11","./picture/btn10","./picture/btn9","./picture/btn8","./picture/btn7","./picture/btn6",
                        "./picture/btn5","./picture/btn4","./picture/btn3","./picture/btn2","./picture/btn1"};

    //遍历各个文件夹显示所有图片信息
    for(int i=0;i<12;i++)
    {
        //Qir定义文件路径
        QDir dir(paths[i]);
        //创建文件筛选链表
        QStringList moviefilenames;
        //添加文件后缀为.png的筛选类型
        moviefilenames << "*.png" << "*.jpg";
        //创建并初始化符合要求的图片到String链表中
        QStringList files = dir.entryList(moviefilenames,QDir::Files|QDir::Readable,QDir::Name);
        //遍历文件链表,将每张图片路径和图片名作为QListWidget的项目添加到QListWidget窗口中
        for(int j = 0; j < files.size(); ++j)
        {
            QString moviename = files.at(j).mid(0,files.at(j).size()-4);
            QListWidgetItem *newitem = new QListWidgetItem(QIcon(QPixmap(paths[i]+"/"+files.at(j))),moviename);
           // newitem->setSizeHint(QSize(,400));   //设置每个item大小
            this->videowins->addItem(newitem);
        }
    }
}

startWin *startWin::getInstance()
{
    //判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
    if(startWin::start == nullptr)
    {
        startWin::start = new startWin();
    }
    return startWin::start;
}

void startWin::closeEvent(QCloseEvent *event)
{
    //创建提示窗口
    QMessageBox *closeMessage = new QMessageBox(QMessageBox::InfORMation,"温馨提示","确认是否退出");
    //显示提示窗口
    closeMessage->show();
    //设置提示窗口按钮
    closeMessage->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
    //接收关闭返回值
    int rec = closeMessage->exec();
    //若点击确定按钮
    if(rec == QMessageBox::Ok)
    {
        event->accept();
    }
    //若点击取消按钮
    else
    {
        event->ignore();
    }
}

void startWin::choseSolt()
{
    //获取触发槽函数的信号
    QString btnText = ((QPushButton*)sender())->text();
    qDebug() << btnText;
    //定义文件路径
    QString path;
    //根据点击不同按钮,设置不同文件路径
    if(btnText == "全部")
    {
        path = "./picture/all";
    }
    if(btnText == "电视剧")
    {
        path = "./picture/btn1";
    }
    if(btnText == "电影")
    {
        path = "./picture/btn2";
    }
    if(btnText == "综艺")
    {
        path = "./picture/btn3";
    }
    if(btnText == "儿童")
    {
        path = "./picture/btn4";
    }
    if(btnText == "动漫")
    {
        path = "./picture/btn5";
    }
    if(btnText == "游戏")
    {
        path = "./picture/btn6";
    }
    if(btnText == "纪录片")
    {
        path = "./picture/btn7";
    }
    if(btnText == "体育")
    {
        path = "./picture/btn8";
    }
    if(btnText == "知识")
    {
        path = "./picture/btn9";
    }
    if(btnText == "直播")
    {
        path = "./picture/btn10";
    }
    if(btnText == "随刻热点")
    {
        path = "./picture/btn11";
    }
    //获取QListWidget的item数
    int count = this->videowins->count();
    //删除QListWidget所有item
    for(int i=0;i<count;i++)
    {
        QListWidgetItem *item = this->videowins->takeItem(0);
        delete(item);
    }
    //将对应路径下的所有图片加载到QListWidget中
    QDir dir(path);
    QStringList moviefilenames;
    moviefilenames << "*.png" << "*.jpg";
    QStringList files = dir.entryList(moviefilenames,QDir::Files|QDir::Readable,QDir::Name);
    for(int i = 0; i < files.size(); ++i)
    {
        QString moviename = files.at(i).mid(0,files.at(i).size()-4);
        QListWidgetItem *newitem = new QListWidgetItem(QIcon(QPixmap(path+"/"+files.at(i))),moviename);
        //newitem->setSizeHint(QSize(240,200));   //设置每个item大小
        videowins->addItem(newitem);
    }
}


void startWin::setQss(QString filename)
{
    QFile file(filename);
    file.open(QFile::ReadOnly);
    QTextStream filetext(&file);
    QString stylesheet = filetext.readAll();
    this->setStyleSheet(stylesheet);
    file.close();
}


void startWin::settingSlot()
{
    setWin *setting = setWin::getInstance();
    setting->setWindowFlags(Qt::windowstaysOnBottomHint); //窗口置于顶部
    setting->setWindowModality(Qt::ApplicationModal); //阻塞除当前窗体之外的所有的窗体
    setting->show();
}

4.setwin.h文件

#ifndef SETWIN_H
#define SETWIN_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>

class setWin : public QWidget
{
    Q_OBJECT
private:
    explicit setWin(QWidget *parent = 0);
    static setWin *setting;
public:
    static setWin *getInstance();
    QLabel *label;
    QPushButton *pushButton;
    QComboBox *combo;
signals:

public slots:
    void changeQssColor();
};

#endif // SETWIN_H

5.setwin.cpp文件

#include <QStringList>
#include "setwin.h"
#include "startWin.h"

setWin* setWin::setting = nullptr;

setWin::setWin(QWidget *parent) : QWidget(parent)
{
    //设置窗口大小
    this->setFixedSize(300,200);

    //创建标签
    this->label = new QLabel("皮肤设置",this);
    this->label->setGeometry(125,20,80,50);

    //创建按钮
    this->pushButton = new QPushButton("确定",this);
    this->pushButton->setGeometry(210,90,50,30);
    connect(this->pushButton,SIGNAL(clicked(bool)),this,SLOT(changeQssColor()));

    //创建下拉框
    this->combo = new QComboBox(this);
    this->combo->move(50,90);
    this->combo->setFixedSize(150,30);
    QStringList QssColor;
    QssColor << "清新绿" << "天际蓝" << "低调灰" << "活力紫";
    this->combo->addItems(QssColor);
}

setWin *setWin::getInstance()
{
    //判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
    if(setWin::setting == nullptr)
    {
        setWin::setting = new setWin();
    }
    return setWin::setting;
}

void setWin::changeQssColor()
{
    //接收下拉框当前文本信息
    QString str = this->combo->currentText();

    //获取主界面
    startWin *start = startWin::getInstance();

    //根据下拉框信息,设置不同皮肤
    if(str == "天际蓝")
    {
        start->setQss("./qss/start1.qss");
    }
    else if(str == "低调灰")
    {
        start->setQss("./qss/start2.qss");
    }
    else if(str == "清新绿")
    {
        start->setQss("./qss/start3.qss");
    }
    else if(str == "活力紫")
    {
        start->setQss("./qss/start4.qss");
    }

    //关闭设置界面
    this->close();
}

6.图片素材及qss文件

   关注博主并在该篇文章下方评论写下邮箱地址,图片素材及相应的qss文件将以压缩包形式发送。

附:QSS样式表属性及含义

    QSS样式表属性可查看:CSDN博主「我是唐」的原创文章《Qt_QSS 样式表属性大全》,原文链接:https://blog.csdn.net/qq_41673920/article/details/97116143。

总结

   以上就是QSS样式表实现界面换肤的所有内容,希望大家阅读后都能有所收获!原创不易,转载请标明出处,若文章出现有误之处,欢迎读者留言指正批评!

到此这篇关于QSS样式表实现界面换肤的文章就介绍到这了,更多相关QSS样式表内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章