Qt - 换肤功能实现

前言

人靠衣装马靠鞍,最近还在为我的 UHelper(GayHub) 添砖加瓦,由于规划的设置里包含了换肤功能,这就来学习下怎么实现。

Qt 的换肤可通过以下几种方式实现,且听我 一 .一 道来:

  • Qt内置风格
  • QPalette
  • QSS

Qt内置风格

Qt 是一个跨平台的类库,相同的界面组件在不同的操作系统上显示的效果不一样。QStyle 是封装了 GUI 界面组件外观 的抽象类。Qt 定义了一些 QStyle 的子类以应用于不同的操作系统,这就是Qt 内置的风格。例如 QStyle 列举个 QComboBox 不同样式下的外观:
在这里插入图片描述
但是这些样式在我们的运行环境下并非完全支持;我们可以通过 QStyleFactory::keys()打印系统所支持的内置风格:

foreach (const QString mFactory,QStyleFactory::keys()) {
    
    
         qDebug() << mFactory;
 }

Win7-64 打印结果:
在这里插入图片描述
值得 注意 的是,选用 Qt 内置的界面风格只是改变控件风格(QPushButtonQLineEdit …)。

并不会改变窗体风格(标题栏最小化最大化关闭按钮 …),若想改变窗口风格,只能自行绘制 1

//等同于QApplication::setPalette(palette);
qApp->setStyle(QStyleFactory::create("Fusion"));
//选择风格默认颜色
qApp->setPalette(QApplication::style()->standardPalette());

QPalette

QPalette Class 中提到,Qt 所有的小部件都包含一个调色板 2

调色板包含三个颜色组:

  • 活动,活动组用于具有键盘焦点的窗口。
  • 禁用,用于因某些原因禁用的窗口小部件(非Windows)。
  • 不活动,不活动组用于其他窗口。

在大多数样式中,活动不活动 外观相同。

我们可以使用 setColor( )setBrush( ) 为调色板的任何颜色组中的特定角色设置颜色和画笔。

这个特定角色在 ColorRole枚举 中被定义,下面列举了核心角色:

更详尽的内容可到 enum QPalette::ColorRole 查看。

在这里插入图片描述
警告:某些样式如果使用本机主题引擎,则不会在所有图形上使用调色板。 Windows VistamacOS 样式均是如此。

qApp->setStyle(QStyleFactory::create("Fusion"));
qApp->setPalette(QApplication::style()->standardPalette());

QPalette palette;
palette.setColor(QPalette::Window, QColor(120,120,120));
palette.setColor(QPalette::WindowText, Qt::white);
palette.setColor(QPalette::Base, QColor(53,53,53));
palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
palette.setColor(QPalette::ToolTipBase, Qt::white);
palette.setColor(QPalette::ToolTipText, Qt::white);
palette.setColor(QPalette::Text, Qt::white);
palette.setColor(QPalette::Button, QColor(53,53,53));
palette.setColor(QPalette::ButtonText, Qt::white);
palette.setColor(QPalette::BrightText, Qt::red);
palette.setColor(QPalette::Highlight, QColor(142,45,197).lighter());
palette.setColor(QPalette::HighlightedText, Qt::black);

qApp->setPalette(palette);

效果

在这里插入图片描述
ps:可以发现窗体(标题栏等)的颜色并没有给变。若想该表标题栏颜色,有两种做法:

  • 调用对应操作系统相关的 API
  • 自定义的标题栏 + CSS background-color

QSS

Qt 的样式表是用于定制用户界面的强有力机制,其是受到 CSS 启发而产生的。

QSS 是纯文本的格式定义,在应用程序运行时可以载入和解释这些样式定义。

使用 QSS 可以定义各种界面组件的样式,从而产生不同的效果。

QSS样式

官方参考文档: Qt Style Sheets Reference

一般样式

QSS 的句法与 CSS 几乎相同。

Qt样式表 包含一系列的 样式法则,一个样式法则由一个 选择器 和一些 声明 组成 3

QPushButton{
    
    
	font:12pt "仿宋";
	background-color: red;
	border: none;
}

选择器

这里 QPushButton 就是 选择器,后面 { } 里的样式声明应用于 QPushButton 及其子类

样式声明部分是 样式法则列表 ,每个样式法则由 属性 组成,每条法则由分号结尾。

子控件

对于一些组合的控件,需要对其子控件进行选择,例如 QComboBox 的下拉按钮,通过选择器的子控件可以对这些界面元素进行显示效果控制:

QComboBox::drop-down
{
    
    
	/*这里用到资源里的down.png*/
    image: url(:/image/down.png);
}

伪状态

选择器可使用伪状态,使得样式只能应用于控件的某个状态。可以看成是一种 条件应用法则

伪状态出现在选择器的后面,使用 : 隔开:

/*
* QPushButton 被选中时变更颜色
*/
QPushButton:checked{
    
    
    background-color: #76797C;
    border-color: #6A6969;
}
/*
* 对伪状态取反
* 表明 read-only 属性为flase 时的状态
*/
QLineEdit:!read-only{
    
    
    background-color: rgb(255,255,0);
}
/* 
* 串联使用,相当于逻辑与
* 当鼠标位于QCheckBox上方且QCheckBox被选中时,字体变红
*/
QCheckBox:hover:checked{
    
    
	color:red;
}

/* 
* 并联使用,相当于逻辑或
* 当鼠标位于QCheckBox上方或QCheckBox被选中时,字体变红
*/
QCheckBox:hover,QCheckBox:checked{
    
    
	color:red;
}

属性

前面说到每个样式法则由属性和值组成。

前面提及的使用样式表定义组件复杂的显示过程外,我们还可以通过盒模型表示:

在这里插入图片描述
图片来自 Customizing Qt Widgets Using Style Sheets

名词解释

  • content:显示内容矩形区域
  • padding:包围 content 的矩形区域
  • boorder:包围 padding 的矩形边框
  • marginboorder 与父组件之间的留白
QLineEdit{
    
    
    /*定义最大最小宽度*/
    min-width:50px;
    max-width:40px;
    
    /*设定上、右、下、左 的宽度*/
    padding:0px 10px 0 px 10px;
    
    /*分别为边框线宽,线形,颜色*/
    border:2px solid red;
    
    /*border与父控件上下左右各留白10px*/
    margin:10px 10px 10px 10px
}

注意

缺省状态下,marginboorder-width、padding0

这种情况下,四个同心矩形就是一个重合的矩形。

使用

那么写完的 QSS样式 需要怎么使用呢?

很简单,通过 setStyleSheet( ) 进行设置:

this->setStyleSheet("QPushButton{"
                    "background-color: red;"
                    "border: none;}"
                    );
//取消所有样式
this->setStyleSheet("");

分离QSS

如果我们写了非常多的 QSS 去描述 组件UI,通过上面这种写法。代码非常长,而且维护起来很头疼。

此外上面的方法将样式固定在了代码中,实现皮肤切换并不方便。

那有没有办法把 QSS 分离处理,每个皮肤单独作为一个 .qss文件,使用时再加载呢?
在这里插入图片描述
这里我使用的是将 qss文件 添加到资源文件再使用 setStyleSheet( ) 加载的做法。

QFile qss(":/qss/dark.qss");
qss.open(QFile::ReadOnly);
qApp->setStyleSheet(qss.readAll());
qss.close();

推荐工具

Qsseditor

该软件用于编辑和浏览实时的样式,能大大提高工作效率。

在这里插入图片描述
下载地址(可戳)

已经看到不少博主推荐该软件了,但是该软件没有自动补全功能,且若存在语法错误也只是红色显示而已,对于刚接触 QSS 的人不太友好,需要经常查文档手册。

QssStylesheetEditor

可以说是 Qsseditor 的升级版,个人觉得体验非常好的地方有:

  • 支持变量(记得最后 导出 .qss,该编辑器会自动替换变量)
  • 颜色拾取功能
  • 代码自动补全

在这里插入图片描述
下载地址(可戳)

QSS参考

推荐一个GayHub 上的 QSS样式库 GTRONICK/QSS;有 7 种样式可供选择。

参考鸣谢


  1. pezy回答 - Qt如何设置界面风格? ↩︎

  2. QPalette Class ↩︎

  3. 《Qt 5.9 C++ 开发指南》 ↩︎

猜你喜欢

转载自blog.csdn.net/weixin_40774605/article/details/106242671