QSS樣式表實(shí)現(xiàn)界面換膚功能
前言
本篇,我們將對QSS樣式表進(jìn)行簡單介紹,并且使用QSS樣式表實(shí)現(xiàn)界面換膚功能。
一、實(shí)現(xiàn)效果
通過點(diǎn)擊主界面的設(shè)置按鈕,進(jìn)入皮膚設(shè)置界面。選擇想要設(shè)置的皮膚,并單擊確定就能實(shí)現(xiàn)界面換膚。

二、QSS簡介及用法
1.什么是QSS?
- QSS是Qt Style Sheet的簡稱,也叫Qt樣式表。在操作Qt制作軟件界面的過程中,允許我們使用QSS自定義小部件的外觀,以及通過子類化QStyle實(shí)現(xiàn)想要的功能界面。
2.怎么使用QSS?
- QSS共有兩種使用方法
- 第一種是窗口內(nèi)的單個(gè)控件直接調(diào)用setStyleSheet函數(shù),將某個(gè)控件的外觀進(jìn)行自定義操作
- 第二種是編寫后綴為.qss文件,通過讀取.qss文件的方式,批量更改窗口內(nèi)所有或部分控件外觀
三、QSS用法一:單個(gè)控件調(diào)用setStyleSheet函數(shù)
- 友情提示:下拉至文章末尾可以查看樣式表屬性及其含義的鏈接
- 調(diào)用語句:控件指針 -> setStyleSheet("控件類型{屬性1:屬性值;屬性2:屬性值;}");
- 調(diào)用實(shí)例如下:
//創(chuàng)建標(biāo)簽
QLabel *title = new QLabel("iQIYI愛奇藝",this);
//標(biāo)簽位置大小初始化
title->setGeometry(250,265,180,50);
//使用樣式表自定義標(biāo)簽外觀
title->setStyleSheet("QLabel{font-size:30px;font-style:微軟雅黑;font-weight:bold}");以上案例實(shí)現(xiàn)了,將標(biāo)簽中的文字設(shè)置為:
30px(字號),微軟雅黑(字體),bold(加粗)。
四、QSS用法二:編寫單個(gè)界面.qss文件的并讀取
1.創(chuàng)建qss文件
(1)在工程文件中,創(chuàng)建新建文本文檔(記事本)、

(2)將新建文本文檔后綴改為.qss

(3)以記事本打開的方式對.qss文件進(jìn)行編輯

2. qss文件語法格式
- 語法格式:
選擇器{屬性1:屬性值;屬性2:屬性值;} - 選擇器類型如下表格:
| 類型 | 實(shí)例 | 含義 |
|---|---|---|
| 通配選擇器 | * | 匹配所有控件 |
| 類型選擇器 | QPushButton | 匹配所有QPushButton和其子類的實(shí)例 |
| 屬性選擇器 | QPushButton[flat="false"] | 匹配所有flat屬性是false的QPushButton實(shí)例(可以是自定義屬性,) |
| 類選擇器 | .QPushButton | 匹配所欲哦QPushButton的實(shí)例,但不匹配其子類,注意前面有一個(gè)點(diǎn)號 |
| ID選擇器 | #myButton | 匹配所有id為myButton的控件實(shí)例,這里的id需要用setObjectName函數(shù)設(shè)置 |
| 后代選擇器 | QDialog QPushButton | 所有QDialog容器中包含的QPushButton(直接或間接) |
| 子選擇器 | QDialog > QPushButton | 所有QDialog容器下面的QPushButton(直接) |
.qss文件實(shí)例

3.讀取qss文件
我們可以在窗口中,以讀入qss文件到字符串的方式,設(shè)置該窗口的QSS,具體代碼如下。
void startWin::setQss(QString filename)
{
//創(chuàng)建文件
QFile file(filename);
//只讀方式打開文件
file.open(QFile::ReadOnly);
//將文件轉(zhuǎn)換成文本流形式
QTextStream filetext(&file);
//將文本流中的所有字符存入新建字符串
QString stylesheet = filetext.readAll();
//設(shè)置該窗口的QSS
this->setStyleSheet(stylesheet);
//關(guān)閉文件
file.close();
}
4.界面換膚
- 提前創(chuàng)建好同一界面下,不同控件外觀的qss文件,如下圖所示。

以信號觸發(fā)的方式進(jìn)行換膚,下圖為按鈕單擊信號觸發(fā)的槽函數(shù)
void setWin::changeQssColor()
{
//接收下拉框當(dāng)前文本信息
QString str = this->combo->currentText();
//獲取主界面
startWin *start = startWin::getInstance();
//根據(jù)下拉框信息,設(shè)置不同皮膚
if(str == "天際藍(lán)")
{
start->setQss("./qss/start1.qss");
}
else if(str == "低調(diào)灰")
{
start->setQss("./qss/start2.qss");
}
else if(str == "清新綠")
{
start->setQss("./qss/start3.qss");
}
else if(str == "活力紫")
{
start->setQss("./qss/start4.qss");
}
//關(guān)閉設(shè)置界面
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;
/***************************************************************
* 函數(shù)名稱: startWin
* 函數(shù)功能: 默認(rèn)構(gòu)造函數(shù)
* 參 數(shù): parent:父類窗口
* 返 回 值: 無
***************************************************************/
startWin::startWin(QWidget *parent) : QWidget(parent)
{
//設(shè)置主界面窗口大小
this->setFixedSize(1200,747);
//設(shè)置默認(rèn)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);
/************創(chuàng)建左窗口************/
this->leftWin = new QWidget(this);
this->leftWin->setGeometry(20,0,150,747);
//創(chuàng)建垂直布局管理器
this->leftLayout = new QVBoxLayout(leftWin);
//壓縮布局
this->leftLayout->addStretch();
//創(chuàng)建按鈕內(nèi)容鏈表
QStringList leftList;
leftList << "全部" << "電視劇" << "電影" << "綜藝" << "兒童" << "動(dòng)漫" << "游戲" << "紀(jì)錄片" << "體育" << "知識" << "直播" << "隨刻熱點(diǎn)";
//根據(jù)按鈕鏈表內(nèi)容生成按鈕,并添加到垂直布局管理器
for(int i=0;i<leftList.size();i++)
{
//新建按鈕
QPushButton *newBtn = new QPushButton(leftList.at(i));
//設(shè)置按鈕的objectname
newBtn->setObjectName("newBtn");
//將按鈕添加到垂直布局管理器
leftLayout->addWidget(newBtn);
//設(shè)置各按鈕之間的間隔
leftLayout->addSpacing(16);
//創(chuàng)建按鈕槽函數(shù)
connect(newBtn,SIGNAL(clicked(bool)),this,SLOT(choseSolt()));
}
//設(shè)置按鈕與窗口底部的間隔
leftLayout->addSpacing(10);
/************創(chuàng)建上窗口************/
this->topWin = new QWidget(this);
this->topWin->setGeometry(181,0,1030,70);
//創(chuàng)建水平布局管理器
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("個(gè)人中心",this);
this->newBtn8->setGeometry(690,20,80,30);
this->newBtn8->hide();
//創(chuàng)建輸入框
this->edit1 = new QLineEdit();
this->edit1->setFixedSize(150,30);
this->topLayout->addWidget(edit1);
this->topLayout->addSpacing(10);
//創(chuàng)建搜索按鈕,并添加到水平布局管理器
this->newBtn1 = new QPushButton();
this->newBtn1->setObjectName("newBtn1");
this->newBtn1->setFixedSize(30,30);
this->topLayout->addWidget(newBtn1);
this->topLayout->addSpacing(10);
//創(chuàng)建設(shè)置按鈕,并添加到水平布局管理器
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()));
//創(chuàng)建縮小按鈕,并添加到水平布局管理器
this->newBtn3 = new QPushButton();
this->newBtn3->setObjectName("newBtn3");
this->newBtn3->setFixedSize(30,30);
this->topLayout->addWidget(newBtn3);
this->topLayout->addSpacing(10);
//創(chuàng)建放大按鈕,并添加到水平布局管理器
this->newBtn4 = new QPushButton();
this->newBtn4->setObjectName("newBtn4");
this->newBtn4->setFixedSize(30,30);
this->topLayout->addWidget(newBtn4);
this->topLayout->addSpacing(10);
//創(chuàng)建關(guān)閉按鈕,并添加到水平布局管理器
this->newBtn5 = new QPushButton();
this->newBtn5->setObjectName("newBtn5");
this->newBtn5->setFixedSize(30,30);
this->topLayout->addWidget(newBtn5);
this->topLayout->addSpacing(10);
//創(chuàng)建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);
//存儲(chǔ)每個(gè)文件夾路徑
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"};
//遍歷各個(gè)文件夾顯示所有圖片信息
for(int i=0;i<12;i++)
{
//Qir定義文件路徑
QDir dir(paths[i]);
//創(chuàng)建文件篩選鏈表
QStringList moviefilenames;
//添加文件后綴為.png的篩選類型
moviefilenames << "*.png" << "*.jpg";
//創(chuàng)建并初始化符合要求的圖片到String鏈表中
QStringList files = dir.entryList(moviefilenames,QDir::Files|QDir::Readable,QDir::Name);
//遍歷文件鏈表,將每張圖片路徑和圖片名作為QListWidget的項(xiàng)目添加到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)); //設(shè)置每個(gè)item大小
this->videowins->addItem(newitem);
}
}
}
startWin *startWin::getInstance()
{
//判斷系統(tǒng)是否已經(jīng)有這個(gè)單例,如果有則返回,如果沒有則創(chuàng)建。
if(startWin::start == nullptr)
{
startWin::start = new startWin();
}
return startWin::start;
}
void startWin::closeEvent(QCloseEvent *event)
{
//創(chuàng)建提示窗口
QMessageBox *closeMessage = new QMessageBox(QMessageBox::Information,"溫馨提示","確認(rèn)是否退出");
//顯示提示窗口
closeMessage->show();
//設(shè)置提示窗口按鈕
closeMessage->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
//接收關(guān)閉返回值
int rec = closeMessage->exec();
//若點(diǎn)擊確定按鈕
if(rec == QMessageBox::Ok)
{
event->accept();
}
//若點(diǎn)擊取消按鈕
else
{
event->ignore();
}
}
void startWin::choseSolt()
{
//獲取觸發(fā)槽函數(shù)的信號
QString btnText = ((QPushButton*)sender())->text();
qDebug() << btnText;
//定義文件路徑
QString path;
//根據(jù)點(diǎn)擊不同按鈕,設(shè)置不同文件路徑
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 == "動(dòng)漫")
{
path = "./picture/btn5";
}
if(btnText == "游戲")
{
path = "./picture/btn6";
}
if(btnText == "紀(jì)錄片")
{
path = "./picture/btn7";
}
if(btnText == "體育")
{
path = "./picture/btn8";
}
if(btnText == "知識")
{
path = "./picture/btn9";
}
if(btnText == "直播")
{
path = "./picture/btn10";
}
if(btnText == "隨刻熱點(diǎn)")
{
path = "./picture/btn11";
}
//獲取QListWidget的item數(shù)
int count = this->videowins->count();
//刪除QListWidget所有item
for(int i=0;i<count;i++)
{
QListWidgetItem *item = this->videowins->takeItem(0);
delete(item);
}
//將對應(yīng)路徑下的所有圖片加載到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)); //設(shè)置每個(gè)item大小
videowins->addItem(newitem);
}
}
/***************************************************************
* 函數(shù)名稱: setQss
* 函數(shù)功能: 主界面皮膚設(shè)置
* 參 數(shù): 無
* 返 回 值: 無
***************************************************************/
void startWin::setQss(QString filename)
{
QFile file(filename);
file.open(QFile::ReadOnly);
QTextStream filetext(&file);
QString stylesheet = filetext.readAll();
this->setStyleSheet(stylesheet);
file.close();
}
/***************************************************************
* 函數(shù)名稱: settingSlot
* 函數(shù)功能: 進(jìn)入設(shè)置界面
* 參 數(shù): 無
* 返 回 值: 無
***************************************************************/
void startWin::settingSlot()
{
setWin *setting = setWin::getInstance();
setting->setWindowFlags(Qt::WindowStaysOnBottomHint); //窗口置于頂部
setting->setWindowModality(Qt::ApplicationModal); //阻塞除當(dāng)前窗體之外的所有的窗體
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)
{
//設(shè)置窗口大小
this->setFixedSize(300,200);
//創(chuàng)建標(biāo)簽
this->label = new QLabel("皮膚設(shè)置",this);
this->label->setGeometry(125,20,80,50);
//創(chuàng)建按鈕
this->pushButton = new QPushButton("確定",this);
this->pushButton->setGeometry(210,90,50,30);
connect(this->pushButton,SIGNAL(clicked(bool)),this,SLOT(changeQssColor()));
//創(chuàng)建下拉框
this->combo = new QComboBox(this);
this->combo->move(50,90);
this->combo->setFixedSize(150,30);
QStringList QssColor;
QssColor << "清新綠" << "天際藍(lán)" << "低調(diào)灰" << "活力紫";
this->combo->addItems(QssColor);
}
setWin *setWin::getInstance()
{
//判斷系統(tǒng)是否已經(jīng)有這個(gè)單例,如果有則返回,如果沒有則創(chuàng)建。
if(setWin::setting == nullptr)
{
setWin::setting = new setWin();
}
return setWin::setting;
}
void setWin::changeQssColor()
{
//接收下拉框當(dāng)前文本信息
QString str = this->combo->currentText();
//獲取主界面
startWin *start = startWin::getInstance();
//根據(jù)下拉框信息,設(shè)置不同皮膚
if(str == "天際藍(lán)")
{
start->setQss("./qss/start1.qss");
}
else if(str == "低調(diào)灰")
{
start->setQss("./qss/start2.qss");
}
else if(str == "清新綠")
{
start->setQss("./qss/start3.qss");
}
else if(str == "活力紫")
{
start->setQss("./qss/start4.qss");
}
//關(guān)閉設(shè)置界面
this->close();
}
6.圖片素材及qss文件
關(guān)注博主并在該篇文章下方評論寫下郵箱地址,圖片素材及相應(yīng)的qss文件將以壓縮包形式發(fā)送。
附:QSS樣式表屬性及含義
QSS樣式表屬性可查看:CSDN博主「我是唐」的原創(chuàng)文章《Qt_QSS 樣式表屬性大全》,原文鏈接:https://blog.csdn.net/qq_41673920/article/details/97116143。
總結(jié)
以上就是QSS樣式表實(shí)現(xiàn)界面換膚的所有內(nèi)容,希望大家閱讀后都能有所收獲!原創(chuàng)不易,轉(zhuǎn)載請標(biāo)明出處,若文章出現(xiàn)有誤之處,歡迎讀者留言指正批評!
到此這篇關(guān)于QSS樣式表實(shí)現(xiàn)界面換膚的文章就介紹到這了,更多相關(guān)QSS樣式表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解讀堆排序算法及用C++實(shí)現(xiàn)基于最大堆的堆排序示例
把待排序的數(shù)組構(gòu)造出最大堆是進(jìn)行堆排序操作的基本方法,這里將帶大家來解讀堆排序算法及用C++實(shí)現(xiàn)基于最大堆的堆排序示例,首先從堆排序的概念開始:2016-06-06
C++實(shí)現(xiàn)數(shù)獨(dú)快速求解
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)數(shù)獨(dú)快速求解的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
深入學(xué)習(xí)C語言中memset()函數(shù)的用法
這篇文章主要介紹了深入學(xué)習(xí)C語言中memset()函數(shù)的用法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-08-08
輸入一個(gè)字符串,取出其中的整數(shù)(實(shí)現(xiàn)代碼)
輸入一個(gè)字符串,內(nèi)含所有數(shù)字和非數(shù)字字符。將其中連續(xù)的數(shù)字作為一個(gè)整數(shù),依次存放到一個(gè)數(shù)組中,統(tǒng)計(jì)共有多少個(gè)整數(shù),并輸出這些數(shù)2013-09-09
C語言與java語言中關(guān)于二維數(shù)組的區(qū)別
這篇文章主要介紹了C語言與java語言中關(guān)于二維數(shù)組的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列(面試官的小結(jié))
這篇文章主要給大家介紹了關(guān)于C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的相關(guān)資料,這是來自一名面試官的小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

