编程学习
Qt学习15:QSS界面美化
00 分钟
2023-7-3
2023-11-23
type
status
date
slug
summary
tags
category
icon
password
Email
文章首发于我的个人博客:欢迎大佬们来逛逛
 

Qt样式表

Qt样式表(Qt Style Sheet)是用于定制用户界面的一种机制。
是受到到HTML中的层级样式表CSS(Cascading Style Sheets,CS2S)启发而来,只是Qt样式表是用于窗体界面的。
我们可以使用QSS来完成对软件的换肤功能

我们首先了解一下QSS包括CSS最基本的结构:盒子模型
盒子模型是qss技术所使用的一种思维模型。盒子模型是指将界面设计页面中的内容元素看作一个个装了东西的矩形盒子。
每个矩形盒子包括:
  • 内容(content)
  • 内边距(padding)
  • 边框(border)
  • 外边距(margin)。
我们可以设置这些不同的参数来完成对他们的调节。
notion image

如何编写样式表?

我们选择一个最基本的Label作为演示:
notion image
然后右键这个Label,选择改变样式表
notion image
notion image
我们就可以在这个窗口中愉快的编写样式表了。

font

简单示例:
  • font-family:字体族
  • color:字体颜色
  • font-size:字体尺寸
  • font-weight:字体的宽度样式
  • font-style:字体样式(斜体还是正常)
等同于直接设置 font:font-style font-weight font-size font- faily
中间用空格隔开。
效果如下:
notion image

notion image
notion image

border

  • border-style:设置边框的样式
  • border-color:设置边框颜色
  • border-width:设置边框的宽度。
    • 同理可以使用: border: border-width border-style border-color
notion image
notion image
notion image

padding

设置文本居中对齐,注意QSS没有text-align,因此必须设置内边距padding
在这里我们设置了 padding-left:30px,得到如下的效果,同时也可以直接:
  • padding:上右下左
  • padding-right ,top,bottom
notion image

有关更加详细的层叠样式表的知识请看CSS或QSS文档。

如何高效的编写QSS?

我们注意到在qtcreator上写QSS没有提示,而且字体很小,很丑,我们可以通过以下的方式来在vscode上编写,然后导入到qt项目中,众所周知vscode上具有对CSS语法的提示与高亮功能。
步骤:
  1. 首先vscode上新建一个CSS文件 ,然后保存到qt的项目中,注意就添加一个图片一样,添加一个 qrc文件,然后导入到qrc中。
notion image
  1. 导入到qrc之后,选择拷贝链接,然后转到 widget.cpp 文件中,输入以下的代码:
代表我们创建了一个QFile文件,然后这个文件指向这个样式表,然后我们打开它,直接readAll读取全部内容即可。
测试如下: 成功了。
notion image
因此我们以后编写QSS文件时直接在vscode上编写就可以了。
然后选择运行就行。

选择器

关于选择器的概念与CSS类似。
CSS 选择器规定了 CSS 规则会被应用到哪些元素上,QSS同理。
选择器的类型:

选择器类型

选择器
示例
描述
通用选择器
*
匹配所有控件
类型选择器
QPushButton
匹配给定类型控件,包括子类
类选择器
.QPushButton
匹配给定类型控件,不包括子类
属性选择器
QPushButton[flat="false"]
匹配给定类型控件中符合[属性]的控件
ID选择器
QPushButton#closeBtn
匹配给定类型,且对象名为closeBtn的控件
子孙对象选择器
QDialog QPushButton
匹配给定类型的子孙控件
子对象选择器
QDialog>QPushButton
匹配给定类型的直接子控件
辅助(子控件)选择器
QComboBox::drop-down
复杂对象的子控件
伪状态选择器
QPushButton:hover
控件的特定状态下的样式
并集选择器
QPushButton,QCheckBox

通用选择器

应用到所有的控件中,包括主窗口Widget
请注意:它的优先级是最低的,即如果我们给其他的控件已经设置了样式,则它就是我们设置的那样,如下图,我们已经给QLabel设置了样式了,因此会匹配为QLabel的样式,实际上刚刚我们的QLabel就是一个类型选择器,可以看到类型选择器比通用选择器的优先级高
notion image

类型选择器与类选择器

它就是针对某个控件的样式设置,注意它包含子类。
即如果我们对QAbstractButton设置了样式,则QPushButton的样式也会改变,因为QPushButton继承自QAbstractButton。
可以看到所有的按钮都被设置样式了。
notion image
对于类选择器,可以说他是真正的精准匹配的方式。
只需要在前面添加一个 .
则子类的样式不会被改变,只会匹配具体的控件,显然QAbstractButton不是一个具体的控件。
notion image

属性选择器

对于某些按钮,如QPushButton的checkable属性,我们可以设置这个按钮为无法选中状态,则我们就可以在这个状态设置样式:
我们首先为几个按钮指定以下这个checkable属性,则我们就会发现满足这个属性的控件的样式都被更改了。
notion image
notion image

ID选择器

如果我们指定了某个控件的ID名字实际上就是这个变量的名字,则我们就可以使用ID选择器,
简单来说就是对指定的控件变量设置样式。注意:ID是唯一的。
notion image
notion image

子孙对象选择器

匹配某个控件里的所有的第二个控件的子孙或其本身控件
可以看到QGroupBox中具有一个QPushButtonQRadioButton,他们都继承自QAbstractButton,因此我们可以看到在这个QGroupBox里面的这两个孩子控件都改变样式了。但是在QGroupBox之外的QPushButton却没有改变样式。
notion image

子对象选择器

匹配第一个控件里的所有第二个控件(精准匹配)
可以看到QGroupBox 里面的 QRadioButton 被改变样式了,但是QPushButton没有改变,因为是精准匹配。
notion image

辅助选择器

匹配某个控件的某个部位
在这里我们专门匹配了QComboBox的下拉框drop-down,因此它会匹配某个复杂控件的具体部位,关于这些小部位的名称我们下面在介绍专门的控件美化的时候会说
notion image

伪状态选择器

状态
描述
:disabled
控件禁用
:enabled
控件启用
:focus
控件获取输入焦点
:hover
鼠标在空间上悬停
:pressed
鼠标按下
:checked
控件被选中
:unchecked
控件没有选中
:indeterminate
控件部分被选中
:open
控件
:closed
空间关闭
:on
控件可以切换,且处于on状态
:off
控件可以切换,且处于off状态
!
对以上状态的否定
简单的使用:
鼠标悬停:hover ,鼠标按下:pressed
如下展示了鼠标悬停与按下时候的样式变化
notion image
notion image

控件的美化

QLabel

字体

  • font-family 为设置字体类型,标准形式需要加双引号,不加也可能会生效,具体看系统是否支持,中英文都支持,但要保证字体编码支持,一般程序编码为"utf-8"时没问题。
  • font-size 为设置字体大小,单位一般使用 px 像素
  • font-style 为设置字体斜体样式,italic 为斜体, normal 为不斜体
  • font-weight 为设置字体加粗样式,bold 为加粗, normal 为不加粗
  • font同时设置字体 style weight size family 的样式,但是 style 和 weight 必须出现在开头,size 和 family 在后面,而且 size 必须在 family 之前,否则样式将不生效,font 中不能设置颜色,可以单独设置 style weight 和 size,不能单独设置 family
  • color 为设置字体颜色,可以使用十六进制数表示颜色,也可以使用某些特殊的字体颜色:red, green, blue 等,或者使用 rgb(r,g,b) 和 rgba(r,g,b,a) 来设置,其中 r、g、b、a 值为0~255,如果想不显示颜色可以设置值为透明 transparent

边距

即设置内边距padding的边距。
Tips
在 qss 中,属性 text-align 对 Label 是不起作用的,只能通过设置 padding 来实现文字的显示位置;一般 padding-left 相当于 x 坐标,padding-top 相当于 y 坐标,设置这两个就可以在任意位置显示了
 

边框

  • border-style 为设置边框样式,solid 为实线, dashed 为虚线, dotted 为点线, none 为不显示(如果不设置 border-style 的话,默认会设置为 none)
  • border-width 为设置边框宽度,单位为 px 像素
  • border-color 为设置边框颜色,可以使用十六进制数表示颜色,也可以使用某些特殊的字体颜色:red, green, blue 等,或者使用 rgb(r,g,b) 和 rgba(r,g,b,a) 来设置,其中 r、g、b、a 值为0~255,如果想不显示颜色可以设置值为透明 transparent
  • border同时设置 border 的 width style color 属性,但值的顺序必须是按照 width style color 来写,不然不会生效!

圆角边框

  • border-top-left-radius 为设置左上角圆角半径,单位 px 像素
  • border-top-right-radius 为设置右上角圆角半径,单位 px 像素
  • border-bottom-left-radius 为设置左下角圆角半径,单位 px 像素
  • border-bottom-right-radius 为设置右上角圆角半径,单位 px 像素
  • border-radius 为设置所有边框圆角半径,单位为 px 像素,通过圆角半径可以实现圆形的 Label

背景图片及样式

  • background-color 为设置背景颜色,可以使用十六进制数表示颜色,也可以使用某些特殊的字体颜色:red, green, blue 等,或者使用 rgb(r,g,b) 和 rgba(r,g,b,a) 来设置,其中 r、g、b、a 值为0~255,如果想不显示颜色可以设置值为透明 transparent
  • background-image 为设置背景图片,图片路径为 url(image-path)
  • background-repeat 为设置背景图是否允许重复填充背景,如果背景图片尺寸小于背景实际大小的话,默认会自动重复填充图片,可以设置为 no-repeat 不重复,repeat-x 在x轴重复,repeat-y 在y轴重复
  • background-position 为设置背景图片显示位置,只支持 left right top bottom center;值 left right center 为设置水平位置,值 top bottom center 为设置垂直位置
  • background 为设置背景的所有属性,color image repeat position 这些属性值出现的顺序可以任意

QPushButton


QCheckBox、QRadioButton

QGroupBox

QComboBox

QSpinBox、QTimeEdit、QDateEdit、QDateTimeEdit

QSpinBox 的 subcontrol 有 ::up-button, ::down-button, ::up-arrow, ::down-arrow
  • up-button 显示在 QSpinBox 里,它的 subcontrol-origin 是相对于 QSpinBox的
  • down-button 显示在 QSpinBox 里,它的 subcontrol-origin 是相对于 QSpinBox的
  • up-arrow 显示在 up-button 里,它的 subcontrol-origin 是相对于 up-button 的
  • down-arrwo 显示在 down-button 里,它的 subcontrol-origin 是相对于 down-button 的

QSlider

QSlider 的 subcontrol 有 ::groove(槽),::handle::add-page::sub-page
  • groove 显示在 QSlider 里,它的 subcontrol-origin 是相对于 QSlider 的
  • handle 显示在 groove 里,它的 subcontrol-origin 是相对于 groove 的
  • sub-page 显示在 groove 里,它的 subcontrol-origin 是相对于 groove 的
  • add-page 显示在 groove 里,它的 subcontrol-origin 是相对于 groove 的
  • handle, sub-page, add-page 虽然都显示在 groove 里,但是都可以把它们扩展到 groove 外

QProgressBar

对于 QProgressBar 的 QSS,大多数都是想把 chunk 定义为圆角矩形的样子,但是当它的 value 比较小时,chunk 的圆角会变成直角,即使使用图片都不行,效果很不理想,所以如果要修改 QProgressBar 的外观的话,推荐继承 QProgressBar 自己绘制或者使用 QStyle。
如果最大值和最小值都为0,则会显示一个繁忙提示,等待系统容错处理结束,再继续恢复加载
 

评论
  • Twikoo
  • Valine