前言

  本篇介绍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 的和。
      请自己尝试修改不同的值,对比、计算输出的结果,这样才能更好的理解盒子模型