【Qt】QSS

一.背景介绍

在网页前端开发领域中,CSS是⼀个⾄关重要的部分.描述了⼀个网页的"样式".从而起到对⽹⻚美化的作用.

 所谓样式,包括不限于大小,位置,颜色,背景,间距,字体等等.

Qt仿照 CSS 的模式,引⼊了QSS,来对Qt中的控件做出样式上的设定,从而允许程序猿写出界⾯更好看的代码.

当然,由于Qt本身的设计理念和网页前端还是存在⼀定差异的,因此QSS中只能⽀持部分 CSS 属性.整体来说QSS要⽐CSS更简单⼀些.

二.基本语法

选择器 {

属性名:属性值

}

• 选择器描述了"哪个widget要应⽤样式规则".

 • 属性则是⼀个键值对,属性名表⽰要设置哪种样式,属性值表⽰了设置的样式的值.

代码示例:

创建一个按钮

修改代码

ui->pushButton->setStyleSheet("QPushButton {color: blue;background:silver}");

运行结果:

注:此时我们仅针对第一个按钮设置样式,此时新建按钮不受影响

三.设置方式

1.指定控件样式设置

 QWidget 中包含了setStyleSheet ⽅法,可以直接设置样式.(如上面eg所示)

另⼀方面,给指定控件设置样式之后,该控件的子元素也会受到影响.

eg:子元素受到影响

创建一个按钮

对widget设置样式

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //对widget进行设置
    this->setStyleSheet("QWidget{color:blue;}");

}

运行结果:

观察到样式对于子控件按钮同样会⽣效.

QPushButton是QWidget的子类

2.全局样式设置

还可以通过QApplication 的 setStyleSheet ⽅法设置整个程序的全局样式.

 全局样式优点:

• 使同⼀个样式针对多个控件⽣效,代码更简洁.

• 所有控件样式内聚在⼀起,便于维护和问题排查.

eg1:使用全局样式

创建多个按钮+使用水平布局管理器管理按钮

修改main函数

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setStyleSheet("QPushButton{color:blue}");
    MainWindow w;
    w.show();
    return a.exec();
}

运行结果:

eg2:样式的层叠特性

 如果通过全局样式给某个控件设置了属性1,通过指定控件样式给控件设置属性2,那么这两个属性都会产生作用。(在两个属性不冲突的前提下)

创建两个按钮+垂直布局管理器管理

修改MainWindow.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setStyleSheet("QPushButton{color:blue}");
    MainWindow w;
    w.show();
    return a.exec();
}

修改widget.cpp

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setStyleSheet("font-size:80px");
}

运行结果:

形如上述这种属性叠加的效果,我们称为"层叠性".

CSS全称为Cascading Style Sheets,其中Cascading就是"层叠性"的意思.QSS也继承了这样的设定

eg3:样式的优先级特性

创建两个按钮

修改MainWindow.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //将全局按钮文字设置为红色
    a.setStyleSheet("QPushButton{color:red}");
    MainWindow w;
    w.show();
    return a.exec();
}

修改widget.cpp

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 将第一个按钮颜色设置为蓝色
     ui->pushButton->setStyleSheet("QPushButton{color:blue}");
}

运行结果:

观察可知,第一个颜色已经改为蓝色。

在CSS中也存在类似的优先级规则.通常来说都是"局部"优先级高于"全局"优先级.

相当于全局样式先"奠定基调",再通过指定控件样式来"特事特办".

关于QSS层叠特性与优先级特性的总结:

若全局与局部设置不冲突,则效果叠加;

若全局与局部设置发生冲突,局部优先级高于全局。

3.从文件加载样式表 

上述代码都是把样式通过硬编码的⽅式设置的.这样使 QSS 代码和 C++ 代码耦合在⼀起了,并不方便代码的维护.因此更好的做法是把样式放到单独的文件中,然后通过读取⽂件的方式来加载样式.

代码示例:从⽂件加载全局样式

1)在界⾯上创建两个按钮

2)创建resource.qrc ⽂件,并设定前缀为/ 

3)创建myQss.qss 文件,修改内容

4)将自定义的myQss.qss文件引入到qrc文件中

5)修改main.cpp,新增⼀个函数⽤来加载样式

QString loadQSS() {
 QFile file(":/myQss.qss");
 // 打开⽂件
 file.open(QFile::ReadOnly);
 // 读取⽂件内容. 虽然 readAll 返回的是 QByteArray, 但是 QString 提供了
//QByteArray 版本的构造函数.
 QString style = file.readAll();
 // 关闭⽂件
 file.close();
 return style;
}

6)修改main.cpp,在main函数中调⽤上述函数,并设置样式

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // 调⽤上述函数加载样式
     const QString& style = loadQSS();
     a.setStyleSheet(style);

    MainWindow w;
    w.show();
    return a.exec();
}

运行结果:

4.使用Qt Designer 编辑样式

QSS 也可以通过 Qt Designer 直接编辑,从⽽起到实时预览的效果.同时也能避免C++和QSS代码的耦合。

eg:使用 Qt Designer 编辑样式

1)在界⾯上创建⼀个按钮

2)右键按钮,选择"改变样式表"

3)在弹出的样式表编辑器中,可以直接填写样式.填写完毕,点击 OK 即可.

4)此时Qt Designer的预览界⾯就会实时显⽰出样式的变化.

运行程序:

当我们发现⼀个控件的样式不符合预期的时候,要记得排查这四个地⽅:

 • 全局样式

• 指定控件样式

• qss⽂件中的样式 

• ui⽂件中的样式

四.选择器

1.选择器分类

eg:使⽤id选择器

1)在界⾯上创建3个按钮, objectName 为 pushButton , pushButton_2 , pushButton_3

2)修改main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // 设置全局样式
     QString style = "";
     style += "QPushButton { color: yellow;  background-color:silver }";
     style += "#pushButton { color: red; }";
     style += "#pushButton_2 { color: green; }";
     a.setStyleSheet(style);

    MainWindow w;
    w.show();
    return a.exec();
}

运行结果:

当某个控件⾝上,通过类型选择器和 ID 选择器设置了冲突的样式时,ID选择器样式优先级更 ⾼.

 同理,如果是其他的多种选择器作⽤同⼀个控件时出现冲突的样式,也会涉及到优先级问题. Qt⽂档上有具体的优先级规则介绍(参The Style Sheet Syntax的Conflict Resolution章节).

实践中我们可以简单的认为,选择器描述的范围越精准,则优先级越高。⼀般来说,ID 选择器优 先级是最⾼的

2.子控件选择器

有些控件内部包含了多个"⼦控件".比如QComboBox 的下拉后的⾯板,比如QSpinBox的上下按钮 等.可以通过⼦控件选择器:: ,针对上述子控件进行样式设置.

eg1:

创建下拉框

在阿里巴巴矢量库中下载图片,保存在qrc文件中

修改main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString style="";
    style+="QComboBox::down-arrow{image:url(:/down.png)}";
    a.setStyleSheet(style);
    MainWindow w;
    w.show();
    return a.exec();
}

运行结果:

eg2:修改进度条的颜色

1)在界⾯上创建⼀个进度条.

2)在Qt Designer 右侧的属性编辑器中,找到QWidget的styleSheet 属性.

 编辑如下内容:

 • 其中的chunk 是选中进度条中的每个"块".使用QProgressBar::text 则可以选中⽂本.

运行结果:

3.伪类属性

3.1概念

伪类选择器,是根据控件所处的某个状态被选择的.

例如按钮被按下,输⼊框获取到焦点,⿏标移动到某个控件上等.

 • 当状态具备时,控件被选中,样式⽣效.

 • 当状态不具备时,控件不被选中,样式失效.

使用:的⽅式定义伪类选择器.

3.2 常用伪类选择器

3.3 代码示例

设置按钮的伪类样式.

1)在界⾯上创建⼀个按钮

2)修改main.cpp文件

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString style="";
    style+="QPushButton{background-color:red}";
    style+="QPushButton:hover{background-color:yellow}";
    style+="QPushButton:pressed{background-color:blue}";
    //设置全局样式
    a.setStyleSheet(style);
    MainWindow w;
    w.show();
    return a.exec();
}

运行结果:

默认时

鼠标放置在按钮上时

鼠标点击时

使用事件也能实现一样效果

五.样式属性

1.概念

QSS中的样式属性⾮常多,不需要都记住.核⼼原则还是⽤到了就去查.⼤部分的属性和CSS是⾮常相似的.

(1)字体

大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX、PD

样式 {font-style: oblique;}(偏斜体) italic;(斜体) normal;(正常)

行高 {line-height: normal;}(正常) 单位:PX、PD、EM

粗细 {font-weight: bold;}(粗体) lighter;(细体) normal;(正常)

变体 {font-variant: small-caps;}(小型大写字母) normal;(正常)

大小写 {text-transform: capitalize;}(首字母大写) uppercase;(大写) lowercase;(小写) none;(无)

修饰 {text-decoration: underline;}(下划线) overline;(上划线) line-through;(删除线) blink;(闪烁)

字体名:

微软雅黑:

Microsoft YaHei

宋体:SimSun

黑体:SimHei

仿宋: FangSong

楷体:  KaiTi

隶书:LiSu

幼圆:YouYuan

华文细黑:STXihei

华文楷体:STKaiti

华文宋体:STSong

华文中宋:STZhongsong

华文仿宋:STFangsong

方正舒体:FZShuTi

方正姚体:FZYaoti

华文彩云:STCaiyun

华文琥珀:STHupo

华文隶书:STLiti

华文行楷:STXingkai

华文新魏:STXinwei

(2)颜色

17种标准色:aqua, black, blue, fuchsia, gray, green, lime, maroon, navy,olive, orange, purple, red, silver, teal, white, yellow

(3)内边距


padding: 4px;                      /* 文字边距 */  
 
padding-left: 5px;                 /* 文字左边距 */  
 
padding-right: 10px;               /* 文字右边距 */  
 
padding-top: 3px;                  /* 文字顶边距 */  
 
padding-bottom: 3px;               /* 文字底边距 */


(4)外边距

margin: 14px 18px 20px 18px; /*外边距 顺序上右下左 */
 
margin-top: 14px;
 
margin-right: 18px;
 
margin-bottom: 20px;
 
margin-left: 18px;


(5) 背景

background-color: #202122;               /* 背景颜色 */  
 
background-color: qlineargradient();    /* 背景颜色:线性渐变*/  
 
background-color: qradialgradient();    /* 背景颜色:辐射渐变*/  
 
background-color: qconicalgradient();   /* 背景颜色:梯形渐变*/  
 
background-image:url(boder.png);        /* 背景图片 */  
 
background-position: ;                 /* 背景图片对齐方式 */  
 
background-repeat: ;                   /* 背景图片平铺方式 */  

(6)边框

border-style: dotted;(点线) dashed;(虚线) solid; double;(双线) groove;(槽线) ridge;(脊状) inset;(凹陷) outset;

border-width:; 边框宽度

border-color:#;

简写方法border:width style color; /*简写*/

border: 1px solid #FDBC03;                       /* 边框:宽度 颜色*/  
 
border-image:url(boder.png) 4 8 12 16;           /* 边界图 切线 */  
 
border-radius: 4px;                              /* 角弧度 */  
 
border-top-left-radius: ;                        /* 角弧度:左上角*/  
 
border-top-right-radius: ;                       /* 角弧度:右上角*/  
 
border-bottom-left-radius: ;                     /* 角弧度:左下角*/  
 
border-bottom-right-radius: ;                    /* 角弧度:右下角*/ 

2.盒子模型

在QSS盒子模型中,一个控件被看作一个矩形的盒子,它由以下几个组成部分构成

内容(Content):盒子中实际包含的内容,如文本、图像等。
内边距(Padding):内容与边框之间的空白区域,用于控制内容与边框之间的间距。
边框(Border):围绕内容和内边距的线条,用于定义控件的边界。
外边距(Margin):盒子与相邻控件之间的空白区域,用于控制盒子与其他控件之间的间距。
这些组成部分构成了一个完整的盒子,它们的大小、样式和颜色都可以通过QSS样式表进行控制。

在QSS中,我们可以使用一些属性来控制盒子模型的各个部分:

width和height属性:用于设置控件的宽度和高度。
padding属性:用于设置内边距的大小,可以通过分别设置上、右、下、左四个方向的内边距。
border属性:用于设置边框的样式、宽度和颜色。
margin属性:用于设置外边距的大小,可以通过分别设置上、右、下、左四个方向的外边距。
这些属性可以通过在QSS样式表中为控件选择器设置相应的属性值来控制盒子模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值