前言
本篇介绍QSS中一个很重要的概念——盒子模型。通过盒子模型,能够十分清楚的了解一个widget的区域组成。
一、简介
Qt中每个widget所在的范围都是一个矩形区域。QSS支持盒子模型,主要由content, padding, border, margin四部分组成,即widget的矩形区域用着四个矩形表示,如图:
- content:绘制内容的矩形区域(绘制文本、图片),Qt自带的widget都是在该区域绘制内容,这只是一个约定,如果你愿意,可以绘制到其它区域。
- padding:内容区和边框之间的间隔
- border:边框,可视化的显示一个widget的逻辑范围,而不一定是widget所占矩形区域的实际大小。
- margin:可以把它想象成widget的矩形区域有一个隐形的边框,margin就是border和这个隐形边框之间的间隔。
QWidget的content, padding, border, margin的矩形区域是一样大的,意思就是,padding, border, margin的值为0,content的矩形区域和QWidget的矩形一样大。但是,QPushButton默认的padding, border, margin的值不为0
Margin,Border,Padding 都分为 4 个部分:上、右、下、左,它们的值可以不同:
二、padding的理解
以padding举例说明,用法如下:
padding: 2px 3px 4px 5px
表示padding-top 为 2px,padding-right 为 3px,padding-bottom 为 4px,padding-left 为 5px,顺序为上、右、下、左,为CSS和QSS的一种规定。
padding: 2px 4px
表示padding-top 和 padding-bottom 为 2px,padding-right 和 padding-left 为 4px
padding: 2px
表示padding-top、padding-right、padding-bottom、padding-left 都为 2px
怎么去理解padding?可以在 Qt Designer 里用 QGridLayout 布局,拖放一个 QLabel 到窗口上,让其占据整个窗口,用下面的 QSS 把 QLabel 的 margin, border,padding 都设置为 50px。如下:
QLabel {
margin: 50px;
border: 50px solid rgb(74, 74, 74);
padding: 50px;
background: white;
}
在Qt Designer里面选中QLabel后:
- 8 个蓝色小方块内就是 QLabel,外面是 parent widget 的,不属于 QLabel
- 标记为 margin 的部分是 margin,为 50px
- 标记为 padding 的部分是 padding,为 50px
- 用工具测量一下,得到 border 的宽也是 50px
- 小虚线方框内是 content rectangle,QLabel 就是在它里面绘制文本,图片等,不会绘制到 padding, border, margin 等上面(如果你自己想继承 QLabel 然后绘制到它们上面当然没问题)
- 当拖动修改窗口的大小后,QLabel 的大小随着改变了,但是 margin, border(宽), padding 的大小都不会变,变化的只有 content rectangle
- Margin 是不可见的,不绘制任何东西
- Padding 是不可见的,但是 QLabel 的背景会绘制到它里面
- Border 是可见的,在背景上面绘制 border(如果 border 是半透明的时候可以看到和背景的融合效果),也就是说,背景会绘制到 padding, border, content 3 个部分上
- Content 是可见的,在背景上绘制 QLabel 的内容:文本,图片
三、总结
Qt 绘制自带的 Widget 时,先绘制 border,然后才绘制 content 的内容,所以,padding 小于 0 时,可以看到 content 绘制到了 border 上。
QWidget::contentsMargins() 获取的不是 margin,而是 margin + border + padding 的和,即content 离边框的距离。
QSS 中设置的 width, height, min-width, max-height 等设置的都是 content width 和 content height,而 QWidget::size() 返回的却是整个 QWidget 的大小,即返回的是 margin + border + padding + content 的和。
请自己尝试修改不同的值,对比、计算输出的结果,这样才能更好的理解盒子模型。