最近在学习使用QSS给Qt程序更换自定义背景皮肤,在此mark。
参考官方文档:http://doc.qt.io/qt-4.8/stylesheet-examples.html
一、清单:
normal.qss --- qss样式
NormalSkin.h --- 一个样式一个类,初始化资源文件,继承自ApplicationSkin
NormalSkin.qrc --- 资源配置文件,指定qss和自定义图片等的路径
ApplicationSkin.h/ApplicationSkin.cpp --- 自定义基类,方便程序管理样式
二、调用实现详解:
1. 原理:利用QWidget类的void setStyleSheet(const QString& styleSheet);,自定义加载皮肤全局函数:
/*QWidget * w:主窗口;QString const & sheetName:样式名*/
void loadStyleSheet(QWidget * w, QString const & sheetName)
{
static QString styleSheet;
if (styleSheet.isEmpty()) {
QFile file(":/qss/" + sheetName.toLower() + ".qss");
file.open(QFile::ReadOnly);
styleSheet = QLatin1String(file.readAll());
file.close();
}
w->setStyleSheet(styleSheet);
}
如果在主UI构建之前调用,则默认每个的UI都用此风格;
2. 自定义初始化函数:
ApplicationSkin * skin_;
void installSkin(ApplicationSkin * skin);
实现:
void myApp::installSkin(ApplicationSkin * skin)
{
skin_ = skin;
}
构造函数中调用:installSkin(ApplicationSkinFactory::createSkin());
3. 加载UI之前调用:
QString const style = theSkin()->styleSheet();
loadStyleSheet(this, style);
即可;
-- 其中:theSkin()->styleSheet();为皮肤名,我用的全局获取函数,方便在应用程序的其他UI上用不同的资源
实现为:
ApplicationSkin * theSkin();
ApplicationSkin * theSkin()
{
if (app_)
return skin_;
// should not happen
return 0;
}
三、效果图
具体代码见:
/**
\file ApplicationSkin.h
\author Jack Li
*/
#ifndef APPLICATION_SKIN_H
#define APPLICATION_SKIN_H
#include
#include
#include
//inline void cleanupOrangeResource() { Q_CLEANUP_RESOURCE(OrangeSkin); }
//inline void cleanupDarkResource() { Q_CLEANUP_RESOURCE(DarkSkin); }
inline void cleanupNormalResource() { Q_CLEANUP_RESOURCE(NormalSkin); }
enum AppSkin {
NMnormal = 0,
NMdark,
NMOrange
};
class ApplicationSkin;
class ApplicationSkinFactory
{
public:
static ApplicationSkin * createSkin();
};
class ApplicationSkin : public QObject {
Q_OBJECT
public:
ApplicationSkin() {}
virtual ~ApplicationSkin() {}
// The name of the stylesheet used as basis for the UI
virtual QString styleSheet() = 0;
// For now, all skins have the same version number
virtual int majorVersion() = 0;
virtual int minorVersion() = 0;
virtual int maintVersion() = 0;
virtual bool testVersion() = 0;
};
#endif // APPLICATION_SKIN_H
/**
\file ApplicationSkin.cpp
\author Jack Li
*/
#include "ApplicationSkin.h"
//#include "resources/orange/OrangeSkin.h"
//#include "resources/dark/DarkSkin.h"
#include "resources/normal/NormalSkin.h"
//#define NMDARK
#ifdef NMORANGE
static AppSkin default_skin = NMOrange;
#else
#ifdef NMDARK
static AppSkin default_skin = NMdark;
#else
static AppSkin default_skin = NMnormal;
#endif
#endif
ApplicationSkin * ApplicationSkinFactory::createSkin()
{
AppSkin manager_skin = default_skin;
//cleanupOrangeResource();
//cleanupDarkResource();
cleanupNormalResource();
switch (manager_skin) {
case NMOrange:
//return new OrangeSkin;
case NMdark:
//return new DarkSkin;
case NMnormal:
return new NormalSkin;
}
return 0;
}
/**
\file NormalSkin.h
\author Jack Li
*/
#ifndef NORMAL_SKIN_H
#define NORMAL_SKIN_H
#include "ApplicationSkin.h"
inline void initNormalResource() { Q_INIT_RESOURCE(NormalSkin); }
class NormalSkin : public ApplicationSkin {
Q_OBJECT
public:
NormalSkin() {
initNormalResource();
}
QString styleSheet() { return "normal"; }
int majorVersion() { return 0; }
int minorVersion() { return 0; }
int maintVersion() { return 1; }
bool testVersion() { return true; }
};
#endif // NORMAL_SKIN_H
qss/normal.qss
/* === QToolTip === */
QToolTip {
background-color: #000000;
border: 2px solid #333333;
color: yellow;
}
/* === QPushButton === */
QPushButton {
border: 1px solid green;
padding: 4px;
min-width: 65px;
min-height: 12px;
}
QPushButton:hover {
background-color: #333333;
border-color: #444444;
}
QPushButton:pressed {
background-color: #111111;
border-color: #333333;
color: yellow;
}
QPushButton:disabled {
color: #454545;
}
QLineEdit, QFrame {
border-width: 1px;
padding: 1px;
border-style: solid;
border-color: darkkhaki;
border-radius: 5px;
}
/* === QComboBox === */
QComboBox {
background-color: green;
border: 1px solid #555;
color: black;
}
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
border-left: 1px solid #333333;
}
/* === QGroupBox === */
QGroupBox {
border: 1px solid #555;
margin-top: 2ex;
}
QGroupBox::title {
color: black;
subcontrol-origin: margin;
subcontrol-position: top left;
border: 1px solid #555;
}
/* As mentioned above, eliminate the padding and increase the border. */
QLineEdit:focus, QFrame:focus {
border-width: 3px;
padding: 0px;
}
/* A QLabel is a QFrame */
QLabel {
border: none;
padding: 0;
background: none;
}
QAbstractScrollArea, QLineEdit, QTextEdit, QAbstractSpinBox, QComboBox {
border-color: #333333;
border: 1px solid #333333;
}
QStackedWidget, QComboBox, QLineEdit, QSpinBox, QTextEdit, QListView, QWebView, QTreeView, QHeaderView {
background-color: cornsilk;
selection-color: #0a214c;
selection-background-color: #C19A6B;
}