目录
基本语法
设置全局样式
问题
分离样式代码
方案1
方案2
选择器
概况
子控件选择器
伪类选择器
盒子模型
修改控件样式示例
按钮
属性小结
复选框
属性小结
输入框
属性小结
列表框
属性小结
渐变色
示例:
菜单栏
设置菜单栏的背景色和各个菜单之间的间距
设置菜单的背景颜色和内边距
设置选中菜单/点击菜单时背景颜色修改
设置菜单项之间的分割线样式
属性小结
登录界面设计
最终效果
设置背景
设置输入框样式
设置按钮样式
完整代码
基本语法
选择器{
属性名:属性值;
}
选择器:先选择某个/某一类控件,接下来进行的各种属性设置,都是针对选中的控件生效的
设置全局样式
界面上所有的样式都集中到一起来组织
在main.cpp中
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QPushButton {color:blue;}");
Widget w;
w.show();
return a.exec();
}
问题
如果设置了全局样式,然后在某个控件里又设置了 其他样式,会怎么样?
如果全局样式与局部样式不冲突的话,两者的样式效果会叠加起来 ,也就是层叠性。
如果设置了全局样式,在某个控件里设置的样式和全局样式冲突了,会怎么样?
如果全局样式与局部样式冲突的话,局部样式的优先级是更高的,覆盖了对应的全局样式。
分离样式代码
方案1
- 创建qrc文件,通过qrc管理样式文件
- 创建单独的qss文件,把这样的文件放到qrc中
- 编写c++代码,读取qss文件中的内容,并设置样式
代码如下:
#include "widget.h"
#include <QApplication>
#include <QFile>
QString loadQSS()
{
QFile file(":/style.qss");
file.open(QFile::ReadOnly);
QString style = file.readAll();
file.close();
return style;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet(loadQSS());
Widget w;
w.show();
return a.exec();
}
方案2
在Qt Designer 中集成了这样的功能,允许我们把样式直接写到.ui文件中。
通过点击如下所示的“改变样式表”,在这里设置样式还能实时预览效果。
综上所述,由于设置样式的方式太灵活了,有很多地方都能设置,就导致当某个控件样式不符合预期的时候,排查起来就比较麻烦。在实际开发中,建议统一使用某一种方式来设置样式。
选择器
概况
qss的选择器支持以下几种:
选择器 | 示例 | 说明 |
---|---|---|
全局选择器
| * |
选择所有的 widget.
|
类型选择器 (type
selector)
|
QPushButton
|
选择所有的 QPushButton 和 其子类 的控件.
|
类选择器 (class selector)
|
.QPushButton
|
选择所有的 QPushButton 的控件. 不会选择子类.
|
ID 选择器
|
#pushButton_2
|
选择 objectName 为 pushButton_2 的控
件.
|
后代选择器
|
QDialog QPushButton
|
选择 QDialog 的所有后代(⼦控件, 孙⼦控件等等) 中的 QPushButton.
|
⼦选择器
|
QDialog > QPushButton
|
选择 QDialog 的所有⼦控件中的QPushButton
|
并集选择器
|
QPushButton, QLineEdit,
QComboBox
|
选择 QPushButton, QLineEdit, QComboBox 这三种控件.
(即接下来的样式会针对这三种控件都⽣效)
|
属性选择器
|
QPushButton[flat="false"
|
选择所有 QPushButton 中, flat 属性为 false 的控件.
|
- 这里要区分类型选择器和类选择器,一个会包含其子类,一个不包含。
- id选择器中的id为控件的ObjectName
- 当 类型选择器和id选择器选中同一控件,并且设置的样式是冲突的,此时id选择器的优先级更高。
子控件选择器
有些控件内部包含了多个 "子控件" . ⽐如 QComboBox 的下拉后的⾯板, 比如 QSpinBox 的上下按钮等。
可以通过子控件选择器 :: , 针对上述子控件进⾏样式设置.
首先我们可以通过qt帮助文档,来查看有哪些子控件,和他们属于哪个控件
示例:修改下拉框的下拉按钮样式
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString style = "QComboBox::down-arrow{image:url(:/down_row.png);}";
a.setStyleSheet(style);
Widget w;
w.show();
return a.exec();
}
效果如下:
伪类选择器
伪类选择器,选中的是控件的“状态”,“符合一定状态条件”的控件。
也就是说
- 当状态具备时,控件被选中,样式生效
- 当状态不具备时,控件不被选中,样式失效
使用 :的方式定义伪类选择器
常用的伪类选择器
伪类选择器 | 说明 |
---|---|
:hover
|
⿏标放到控件上
|
:pressed
|
⿏标左键按下时
|
:focus
|
获取输⼊焦点时
|
:enabled
|
元素处于可⽤状态时
|
:checked
|
被勾选时
|
:read-only
|
元素为只读状态时
|
示例:鼠标悬停字体变红,点击变蓝
QString style = "QPushButton:hover{color:red;}";
style+="QPushButton:pressed{color:blue;}";
a.setStyleSheet(style);
盒子模型
box model
⼀个遵守盒模型的控件, 由上述⼏个部分构成.
- Content 矩形区域: 存放控件内容. ⽐如包含的⽂本/图标等.
- Border 矩形区域: 控件的边框.
- Padding 矩形区域: 内边距. 边框和内容之间的距离.
- Margin 矩形区域: 外边距. 边框到控件 geometry 返回的矩形边界的距离
默认情况下, 外边距, 内边距, 边框宽度都是 0,这与css中的盒模型基本类似
属性 | 说明 |
---|---|
margin
|
设置四个方向的外边距. 复合属性.
|
padding
|
设置四个方向的内边距. 复合属性.
|
border-style
|
设置边框样式
|
border-width
|
边框的粗细
|
border-color
|
边框的颜⾊
|
border
|
复合属性, 相当于 border-style + border-width + border-color
|
修改控件样式示例
按钮
这里区分color和background-color属性,color设置的是字体的属性,background-color设置的是背景颜色。
QPushButton{
font-size:20px;
boder:2px solid rgb(171, 165, 255);
boder-radius:15px;
background-color:rgb(237, 213, 255);
color:white;
}
QPushButton:pressed{
background-color:rgb(156, 110, 255);
}
属性小结
属性 | 说明 |
---|---|
font-size
|
设置文字大小
|
border-radius
|
设置圆⻆矩形
数值设置的越大, 角就 "越圆"
|
background-color
|
设置背景颜色
|
复选框
这里设置复选框未选中、未选中鼠标悬停、勾选时的图标
QCheckBox{
font-size:20px;
}
QCheckBox::indicator{
width:20px;
height:20px;
}
QCheckBox::indicator:unchecked{
image:url(:/checkbox_uncheck.png);
}
QCheckBox::indicator:unchecked:hover{
image:url(:/checkbox.png);
}
QCheckBox::indicator:checked{
image:url(:/checkbox_check.png)
}
属性小结
要点 | 说明 |
---|---|
::indicator
|
⼦控件选择器.
选中 checkbox 中的对钩部分.
|
:hover
| 伪类选择器. 选中⿏标移动上去的状态. |
:pressed
|
伪类选择器.
选中⿏标按下的状态.
|
:checked
|
伪类选择器.
选中 checkbox 被选中的状态.
|
:unchecked
|
伪类选择器.
选中 checkbox 未被选中的状态.
|
width
|
设置⼦控件宽度.
对于普通控件⽆效 (普通控件使⽤ geometry 方式设定尺⼨).
|
height
|
设置⼦控件⾼度.
对于普通控件⽆效 (普通控件使⽤ geometry 方式设定尺⼨)
|
image
|
设置⼦控件的图⽚.
像 QSpinBox, QComboBox 等可以使⽤这个属性来设置⼦控件的图⽚
|
单选框的设置与复选框类似,两者涉及属性基本上一样,这里就不再介绍。
输入框
QLineEdit{
border-width:1px;
border-radius:10px;
border-color:rgb(148, 255, 252);
border-style:inset;
padding:0 8px;
color:rgb(255, 255, 255);
background:rgb(100, 100, 100);
selection-background-color:rgb(255, 255, 0);
selection-color:rgb(121, 121, 121);
}
属性小结
属性 | 说明 |
---|---|
border-width
|
设置边框宽度
|
border-radius
|
设置边框圆⻆
|
border-color
|
设置边框颜⾊
|
border-style
|
设置边框⻛格
|
padding
|
设置内边距
|
color
|
设置⽂字颜⾊
|
background
|
设置背景颜⾊
|
selection-background-color
|
设置选中⽂字的背景颜⾊
|
selection-color
|
设置选中⽂字的⽂本颜⾊
|
列表框
属性小结
属性 | 说明 |
---|---|
::item
|
选中 QListView 中的具体条⽬
|
:hover
|
选中⿏标悬停的条⽬
|
:selected
|
选中某个被选中的条⽬
|
background
|
设置背景颜⾊
|
border
|
设置边框
|
qlineargradient
|
设置渐变⾊
|
渐变色
qlineargradient 设置渐变色(线性渐变)
此处要填写六个参数:
- x1:起点的横坐标
- y1:起点的纵坐标
- x2:终点的横坐标
- y2:终点的纵坐标
这里的取值非常有限,要么是0,要么是1
- 起点为(0,0)终点是(1,0)就是横向的渐变、
- 起点为(0,0)终点是(0,1)就是竖向的渐变、
- 起点为(0,0)终点是(1,1)就是对角线的渐变
如下图所示:
另外两个参数就是
- stop:0 起始颜色
- stop:1 结束颜色
示例:
QListWidget::item:hover{
background:qlineargradient(x1:0,y1:0,x2:0,y2:1,
stop:0 #FAFBFE,stop:1 #DCDEF1);
}
QListWidget::item:selected{
boder:1px solid #6a6ea9;
background:qlineargradient(x1:0,y1:0,x2:0,y2:1);
}
效果如下:
菜单栏
设置菜单栏的背景色和各个菜单之间的间距
QMenuBar{
background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,
stop:0 lightgray,stop:1 darkgray );
spacing:3px;
}
设置菜单的背景颜色和内边距
QMenuBar::item{
padding:1px 4px;
background:transparent;
border-radius:4px;
}
设置选中菜单/点击菜单时背景颜色修改
QMenuBar::item:selected{
background:#a8a8a8;
}
QMenuBar::item:pressed{
background:#888888;
}
设置菜单项之间的分割线样式
QMenu::separator{
height:2px;
background:lightblue;
margin-left:10px;
margin-right:5px;
}
完整代码:
QMenuBar{
background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,
stop:0 lightgray,stop:1 darkgray );
spacing:3px;
}
QMenuBar::item{
padding:1px 4px;
background:transparent;
border-radius:4px;
}
QMenuBar::item:selected{
background:#a8a8a8;
}
QMenuBar::item:pressed{
background:#888888;
}
QMenu{
background-color:white;
margin:0 2px
}
QMenu::item{
padding:2px 25px 2px 20px;
border:3px solid transparent;
}
QMenu::item:selected{
border-color:darkblue;
background:rgba(100, 100, 100, 150)
}
QMenu::separator{
height:2px;
background:lightblue;
margin-left:10px;
margin-right:5px;
}
效果如下
属性小结
属性 | 说明 |
---|---|
QMenuBar::item
|
选中菜单栏中的元素.
|
QMenuBar::item:selected
|
选中菜单来中的被选中的元素.
|
QMenuBar::item:pressed
|
选中菜单栏中的⿏标点击的元素
|
QMenu::item
|
选中菜单中的元素
|
QMenu::item:selected
|
选中菜单中的被选中的元素
|
QMenu::separator
|
选中菜单中的分割线.
|
登录界面设计
最终效果
设置背景
在qt中直接给QWidget顶层窗口设置背景图会失效,因此我们可以给上述控件外头套上一个和窗口一样大小的QFrame控件,用来设置背景图。
qt中设置背景图除了background-image之外,还有border-image属性,两者的区别:
- background-image:设计的背景图片固定大小
- border-image:设置的背景图片跟随控件的大小变化
QFrame{
border-image:url(:/background.jpg)
}
使用QVBoxLayout来管理两个输入框和勾选框、按钮;再将这个QVBoxLayout放到一个QFrame中
设置输入框样式
QLineEdit{
color:#8d98a1;
background-color:#405361;
padding:0 5px;
font-size:20px;
border-style:none;
border-radius:10px;
}
设置按钮样式
QPushButton{
font-size:20px;
color:white;
background-color:#555;
border-style:outset;
border-radius:10px;
}
QPushButton:pressed{
color:black;
background-color:#ce1db;
border-style:inset;
}
完整代码
QFrame{
border-image:url(:/background.jpg)
}
QLineEdit{
color:#8d98a1;
background-color:#405361;
padding:0 5px;
font-size:20px;
border-style:none;
border-radius:10px;
}
QCheckBox{
color:white;
background-color:transparent;
}
QPushButton{
font-size:20px;
color:white;
background-color:#555;
border-style:outset;
border-radius:10px;
}
QPushButton:pressed{
color:black;
background-color:#ce1db;
border-style:inset;
}