目录
前言:
Qt中的QSS(Qt Style Sheets)作用是美化界面,他可以对控件的样式进行设计,比如控件的颜色、字体、位置、边框等属性。QSS是依照CSS而来的,而CSS是网页前端开发中最重要的一个工具,不过QSS只支持部分CSS属性,因此QSS会比CSS更简单⼀些。值得注意的是:当通过QSS设置样式和通过C++代码设置样式冲突时,QSS的优先级会更高。
1、QSS的语法介绍
QSS的基本语法非常简单,由选择器,属性名,属性值构成,如下:
选择器 {
属性名: 属性值;
}
其中,选择器表示要设置样式的控件,属性名表示具体设计哪些样式,属性值表示设置样式的方式。举个例子,比如:
QPushButton {
color: red;
}
上述代码表示,将当前界面下的所有QPushButton(选择器)的文本颜色(属性名)变为红色(属性值)。
2、QSS的基本使用
在ui文件中创建一个QPushButton,让该控件调用setStyleSheet函数,并将QSS作为该函数的参数。设计如下图:
在widget.cpp中进行样式设计,代码如下:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton1->setStyleSheet("QPushButton{color:red;}");
}
Widget::~Widget()
{
delete ui;
}
运行结果:
解释:上述代码表示对按钮1这个控件内所有名为QPushButton的控件的文本颜色设为红色,注意这里调用setStyleSheet函数的控件是按钮1而不是widget,因此不会更改按钮2的样式,如果调用者是widget,则会更改按钮1以及按钮2的样式。
3、QSS的全局设置
通过QApplication的对象调用setStyleSheet,从而设置整个程序的全局样式,全局样式优点: 1、使同⼀个样式针对多个控件生效, 代码更简洁,2、所有控件样式内聚在⼀起, 便于维护和问题排查。界面设计如下:
代码如下(注意是在main.cpp文件中):
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QPushButton{color:blue;}");//全局设置
Widget w;
w.show();
return a.exec();
}
运行结果:
4、样式的叠加特性
通过QSS设置的样式是可以叠加的,比如在全局设置的样式可以和局部设置的样式叠加,并且调用setStyleSheet时可以叠加设置多个样式,依照上述例子的界面,测试如下。
局部设置样式的代码:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置字体尺寸
ui->pushButton1->setStyleSheet("QPushButton{font-size:80px};");
}
Widget::~Widget()
{
delete ui;
}
全局设置样式的代码:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QPushButton{color:blue;background:red}");//设置多项属性
Widget w;
w.show();
return a.exec();
}
运行结果:
从结果可以发现设置的样式可以进行叠加。
5、样式的优先级
对一个控件的同一个属性先进行局部设置样式,再进行全局设置样式,则该控件的属性最终为局部设置的样式,即局部优先于全局,测试代码如下。
widget.cpp代码:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton->setStyleSheet("QPushButton{color:red;}");
}
Widget::~Widget()
{
delete ui;
}
main.cpp代码:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
a.setStyleSheet("QPushButton{color:blue;}");
return a.exec();
}
运行结果:
可以看到,即使全局设置的代码在局部设置之后,最终的样式依然是局部代码设置的样式。所以通常使用全局设置“奠定基调”,然后使用局部设置进行“微调”。
6、使用Qt Designer设置样式
上述设置样式都是用代码的形式进行设置的,除了代码的形式,还可以在ui文件中(即Qt Designer)设置样式,步骤如下。
1、先进入ui文件,右键点击控件,点击改变样式表:
2、在输入框中直接输入QSS,点击OK即可完成样式的设置,如下图:
7、选择器种类介绍
QSS中的选择器表示要设置的控件,但是他可以有多种种类,常用的种类介绍如下(以QPushButton为例):
选择器种类 | 示例 | 说明 |
全局选择器
|
* |
选择当前控件下的所有控件
|
类型选择器
|
QPushButton
|
选择当前控件下QPushButton控件,以及其子类 |
类选择器
|
.QPushButton | 选择当前控件下QPushButton控件,不会选择其子类 |
ID 选择器
|
#pushButton_1
|
指定选择名 为 pushButton_2 的控件
|
并集选择器
|
xx,yy,zz | 选择xx,yy,zz三种控件 |
属性选择器
|
QPushButton[flat="false"]
|
选择所有PushButton中,flat属性为false的控件
|
上文例子中的选择器都是类型选择器,下面测试一些其他的常用选择器种类。
7.1 类选择器
先自定义一个继承QPushButton的类,然后将该类实例化到界面上,观察在全局中使用类型选择器和类选择器对该控件属性的影响。
自定义类的mypushbutton.h文件代码如下:
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include <QWidget>
#include <QPushButton>
class mypushbutton : public QPushButton
{
Q_OBJECT
public:
mypushbutton(QWidget *parent = nullptr);
};
#endif // MYPUSHBUTTON_H
widget.cpp代码如下:
#include "widget.h"
#include "ui_widget.h"
#include "mypushbutton.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建自定义按钮
mypushbutton* myQpush = new mypushbutton(this);
myQpush->setText("自定义按钮");
myQpush->move(100,200);
//创建Qt系统按钮
QPushButton* Qpush = new QPushButton("Qt按钮",this);
Qpush->move(200,200);
}
Widget::~Widget()
{
delete ui;
}
先运行上述代码,观看结果:
此时可以看到界面中已有两个按钮,但是一个按钮是用我们自定义的类(mypushbutton)生成的,另一个按钮是用系统提供的QPushButton类生成的。
使用全局设置,选择器的种类选择类选择器,main.cpp代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet(".QPushButton{color:blue;}");//类选择器
Widget w;
w.show();
return a.exec();
}
运行结果:
发现系统原始按钮的样式发生了改变,但是我们自定义的类样式却没有改变,原因就是类选择器不会选择QPushButton的子类,而我们自定义的类刚好是QPushButton的子类,所以我们自定义的按钮样式不会受到改变。如果采用的是类型选择器,则运行结果如下:
7.2 ID选择器
ID选择器就是指定控件ID对其精准的进行样式修改,界面设计如下:
全局设置的代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("#pushButton{color:red;} "
"#pushButton_2{color:blue;} #pushButton_3{color:green;}");
Widget w;
w.show();
return a.exec();
}
运行结果:
7.3 并集选择器
创建一个QLabel、QPushButton、QLineEdit。采用并集选择器对这些控件进行样式修改,界面设计如下:
代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QLabel,QPushButton,QLineEdit{color:red;}");
Widget w;
w.show();
return a.exec();
}
运行结果:
从结果可以看到,使用并集选择器可以用简易的代码给多个控件设置样式,是一种很好的代码复用行为。
8、子控件选择器
有些控件本身自带子控件,比如QComboBox的下拉按钮,以及QSpinBox的上下按钮等。即使是子控件,仍然可以使用QSS对其修改样式,使用子控件选择器”::“即可,比如:QComboBox::down-arrow表示选中了QComboBox的下拉按钮。测试步骤如下。
1、先建立一个Qt虚拟目录(qrc),将图片资源放入到该目录下(关于虚拟目录-qrc见:Qt_控件的QWidget属性介绍-第五点),如下图:
2、在main.cpp中使用全局设置更改该子控件的图标,代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QComboBox::down-arrow{image:url(:/down.png);}");
Widget w;
w.show();
return a.exec();
}
运行结果:
9、伪类选择器
伪类选择器表示控件处于某一状态,比如控件被按下,控件获取到焦点,⿏标移动到某个控件上等,可以使用伪类选择器捕获到这一时刻,然后实现各种效果。与子控件选择器的写法有些相似,伪类选择器用“:”表示,常用的伪类选择器介绍如下:
:hover
|
⿏标放到控件上
|
:pressed
|
⿏标左键按下时
|
:focus
|
获取输⼊焦点时
|
:enabled
|
元素处于可⽤状态时
|
:checked
|
被勾选时 |
:read-only
|
元素为只读状态时
|
测试代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("QPushButton{color:red;}"
"QPushButton:hover{color:blue;}"
"QPushButton:pressed{color:green;}");
Widget w;
w.show();
return a.exec();
}
运行结果:
另外,上述在伪类选择器可以用“!”来表示取反,比如:!hover表示鼠标离开控件时,:!pressed 表示⿏标松开时。
10、盒子模型
盒子模型是一个控件的基础框架,表示一个框架由四个部分构成:
1、内容:指的是控件的文本或者图标。
2、内边距:指的是内容与边框之间的距离。
3、边框:指的是控件周围的边框。
4、外边距:指的是控件与其他控件的距离。
盒子模型示意图如下:
QSS中与边框和边距相关的常用属性名如下:
margin
|
设置四个方向的外边距
|
padding
|
设置四个方向的内边距 |
border-style
|
设置边框样式
|
border-width
|
边框的粗细
|
border-color
|
边框的颜⾊
|
border
|
边框属性的复合用法:border-width+border-style+border-color
|
border-radius | 边框四个角的圆滑度,数值设置的越⼤,⻆就 "越圆" |
10.1 设置边框和内边距
测试给一个QLabel设置边框和内边距,首先在界面上创建一个QLabel,如下图:
代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//设置边框宽5px,边框样式固体,边框颜色蓝色。内左边距50px,边角圆滑50px
a.setStyleSheet("QLabel{border:5px solid blue;padding-left:50px;"
"border-radius:30px;}");
Widget w;
w.show();
return a.exec();
}
运行结果:
结语
以上就是关于Qt中QSS的使用与介绍,QSS所能设置的样式形式非常多,其中控件的属性名远不止上文介绍的那些,控件与控件之间即存在相同的属性名也存在独特的属性名,当然这些属性名不需要都背下来,重要的是掌握QSS的使用,当使用到这些属性名时再去查阅手册。
最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!