自学内容网 自学内容网

[Qt] Box Model | 控件样式 | 实现log_in界面

目录

1、样式属性

(1)盒模型(Box Model)

2、控件样式示例

(1)按钮

(2)复选框

(3)单选框

(4)输入框

(5)列表

【理解渐变色】

(6)菜单栏

(7)登录界面

3、小结


1、样式属性

QSS 中的样式属性非常多,大部分的属性和 CSS 是非常相似的。

  • 文档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控件都能设置哪些属性等。

相关的代码示例,在后面具体介绍。在翻阅文档的时候涉及到一个关键术语 “盒模型”(Box Model)。


(1)盒模型(Box Model)

在文档的 Customizing Qt Widgets Using Style Sheets 的 The Box Model 章节介绍了盒模型:

⼀个遵守盒模型的控件,由上述几个部分构成。

  • Content 矩形区域:存放控件内容,比如包含的文本 / 图标等。
  • Border 矩形区域:控件的边框。
  • Padding 矩形区域:内边距,边框和内容之间的距离。
  • Margin 矩形区域:外边距,边框到控件 geometry 返回的矩形边界的距离。

默认情况下,外边距、内边距、边框宽度都是 0。

可以通过一些 QSS 属性来设置上述的边距和边框的样式:

QSS 属性

说明

margin

设置四个方向的外边距。复合属性。

padding

设置四个方向的内边距。复合属性。

border-style

设置边框样式

border-width

边框的粗细

border-color

边框的颜色


【设置边框和内边距】

A. 在界面上创建一个 label

B. 修改 main.cpp, 设置全局样式

  • border: 20px solid green 相当于 border-style: solid; border-width: 2px; border-color: green; 三个属性的简写形式。
  • padding-left: 50px; 是给左侧设置内边距。

C. 运行程序


【设置外边距】

为了方便确定控件位置,演示外边距效果,使用代码创建⼀个按钮。

A. 修改 widget.cpp,创建按钮,并设置样式

B. 运行程序

可以看到,当前按钮的边框被外边距挤的缩小了,但是获取到的按钮的 Geometry 是不变的。


2、控件样式示例

(1)按钮

【自定义按钮】

A. 界面上创建一个按钮

B. 右键 -> 改变样式表,使用 Qt Designer 设置样式

C. 执行程序

  • 点击 “按钮”:

D. 属性小结

属性

说明

font-size

设置文字大小。

border-radius

设置圆角矩形。
数值设置的越大,角就越圆。

background-color

设置背景颜色。

形如 #dadbde 是计算机中通过十六进制表示颜色的方式。


(2)复选框

【自定义复选框】

A. 创建一个 resource.qrc 文件,并导入以下图片

  • 使用黑色作为默认形态
  • 使用蓝色作为 hover 形态
  • 使用红色作为 pressed 形态

注意这里的文件命名。

B. 创建一个复选框

C. 编辑复选框的样式

QCheckBox {
    font-size: 20px;
}

QCheckBox::indicator {
    width: 20px;
    height: 20px;
}

QCheckBox::indicator:unchecked {
    image: url(:/checkbox-unchecked.png);
}

QCheckBox::indicator:unchecked:hover {
    image: url(:/checkbox-unchecked_hover.png);
}

QCheckBox::indicator:unchecked:pressed {
    image: url(:/checkbox-unchecked_pressed.png);
}

QCheckBox::indicator:checked {
    image: url(:/checkbox-checked.png);
}

QCheckBox::indicator:checked:hover {
    image: url(:/checkbox-checked_hover.png);
}

QCheckBox::indicator:checked:pressed {
    image: url(:/checkbox-checked_pressed.png);
}

D. 运行程序

鼠标点击选中,再取消的过程,可以看到此时的复选框就变得丰富起来了:

E. 小结

要点

说明

::indicator

子控件选择器。
选中 checkbox 中的对钩部分。

:hover

伪类选择器。
选中鼠标移动上去的状态。

:pressed

伪类选择器。
选中鼠标按下的状态。

:checked

伪类选择器。
选中 checkbox 被选中的状态。

:unchecked

伪类选择器。
选中 checkbox 未被选中的状态。

width

设置子控件宽度。
对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

height

设置子控件高度。
对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

image

设置子控件的图片。
像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片。


(3)单选框

【自定义单选框】

A. 创建 resource.qrc 文件,并导入以下图片

  • 使用黑色作为默认形态
  • 使用蓝色作为 hover 形态
  • 使用红色作为 pressed 形态

注意这里的文件命名。

B. 在界面上创建两个单选按钮

要点

说明

::indicator

子控件选择器。
选中 radioButton 中的对钩部分。

:hover

伪类选择器。
选中鼠标移动上去的状态。

:pressed

伪类选择器。
选中鼠标按下的状态。

:checked

伪类选择器。
选中 radioButton 被选中的状态。

:unchecked

伪类选择器。
选中 radioButton 未被选中的状态。

width

设置子控件宽度。
对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

height

设置子控件高度。
对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

image

设置子控件的图片。
像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片。

C. 在 Qt Designer 中编写样式

  • 此处为了让所有 QRadioButton 都能生效,把样式设置在 Widget 上了,并且使用后代选择器选中了 QWidget 里面的 QRadioButton。

注意 :

  • QSS 中有些属性,子元素能继承父元素(例如 font-size、color 等),但是也有很多属性是不能继承的。
  • 具体哪些能继承哪些不能继承,规则比较复杂,我们不去具体研究,实践中我们编写更精准的选择器是上策。
 QWidget QRadioButton {
    font-size: 20px;
}
 
QWidget QRadioButton::indicator {
    width: 20px;
    height: 20px;
}
 
QWidget QRadioButton::indicator:unchecked {
    image: url(:/radio-unchecked.png);
}
 
QWidget QRadioButton::indicator:unchecked:hover {
    image: url(:/radio-unchecked_hover.png);
}
 
QWidget QRadioButton::indicator:unchecked:pressed {
    image: url(:/radio-unchecked_pressed.png);
}
 
QWidget QRadioButton::indicator:checked {
    image: url(:/radio-checked.png);
}
 
QWidget QRadioButton::indicator:checked:hover {
    image: url(:/radio-checked_hover.png);
}
 
QWidget QRadioButton::indicator:checked:pressed {
    image: url(:/radio-checked_pressed.png);
}

D. 运行程序


(4)输入框

【自定义单行编辑框】

A. 在界面上创建一个单行编辑框

B. 在 Qt Designer 中编写样式

QLineEdit {
 border-width: 1px; 
 border-radius: 10px;
 border-color: rgb(58, 58, 58);
 border-style: inset;
 padding: 0 8px;
 color: rgb(255, 255, 255);
 background:rgb(100, 100, 100);
 selection-background-color: rgb(187, 187, 187);
 selection-color: rgb(60, 63, 65);
}

C. 执行程序

输入 "hello world",选中 "rld":

属性

说明

border-width

设置边框宽度。

border-radius

设置边框圆角。

border-color

设置边框颜色。

border-style

设置边框风格。

padding

设置内边距。

color

设置文字颜色。

background

设置背景颜色。

selection-background-color

设置选中文字的背景颜色。

selection-color

设置选中文字的文本颜色。


(5)列表

【自定义列表框】

A. 在界面上创建一个 ListView

操作详见前文:[Qt] 多元素控件 | 容器类控件 | 布局管理器layout

B. 编写代码

QListView::item:hover {
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
 stop: 0 #FAFBFE, stop: 1 #DCDEF1);
}
QListView::item:selected {
 border: 1px solid #6a6ea9;
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
 stop: 0 #6a6ea9, stop: 1 #888dd9);
}

C. 执行程序

要点

说明

::item

选中 QListView 中的具体条目。

:hover

选中鼠标悬停的条目

:selected

选中某个被选中的条目。

background

设置背景颜色

border

设置边框。

qlineargradient

设置渐变色。

对于渐变的理解:

qlineargradient 有 6 个参数。

  • x1, y1:标注了⼀个起点
  • x2, y2:标注了⼀个终点

这两个点描述了⼀个 “方向”

例如

  • x1: 0, y1: 0, x2: 0, y2: 1 就是垂直方向从上向下进行颜色渐变。
  • x1: 0, y1: 0, x2: 1, y2: 0 就是水平方向从左向右进行颜色渐变。
  • x1: 0, y1: 0, x2: 1, y2: 1 就是从左上往右下方向进行颜色渐变.

stop0 和 stop1 描述了两个颜色,渐变过程就是从 stop0 往 stop1 进行渐变的。


【理解渐变色】

A. 界面不创建任何控件

B. 编写样式

QWidget {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #fff, stop: 1 #000);
}

当前按照垂直从上往下从白色过渡到黑色。

C. 修改代码

QWidget {
    background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 #fff, stop: 1 #000);
}

当前按照水平从左往右从白色过渡到黑色。

执行效果:


(6)菜单栏

【自定义菜单栏】

A. 创建菜单栏

创建若干菜单项和一个分隔符:

B. 编写样式

QMenuBar {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 lightgray, stop:1 darkgray);
    spacing: 3px;
}

QMenuBar::item {
    padding: 1px 4px;
    background: transparent;
    border-radius: 4px;
}

QMenuBar::item:selected {
    background: #a8a8a8;
}

QMenuBar::item:pressed {
    background: #888888;
}

QMenu {
    background-color: white;
    margin: 0 2px;
}

QMenu::item {
    padding: 2px 25px 2px 20px;
    border: 3px solid transparent;
}

QMenu::item:selected {
    border-color: darkblue;
    background: rgba(100, 100, 100, 150);
}

QMenu::separator {
    height: 2px;
    background: lightblue;
    margin-left: 10px;
    margin-right: 5px;
}

C. 执行效果

要点

说明

QMenuBar::item

选中菜单栏中的元素。

QMenuBar::item:selected

选中菜单栏中的被选中的元素。

QMenuBar::item:pressed

选中菜单栏中的鼠标点击的元素。

QMenu::item

选中菜单中的元素

QMenu::item:selected

选中菜单中的被选中的元素。

QMenu::separator

选中菜单中的分割线。


(7)登录界面

【基于上述学习过的 QSS 样式,制作一个美化版本的登录界面】

A. 在界面上创建元素,并使用布局管理器把相关元素包裹一下

  • 使用 QVBoxLayout 来管理上述控件。
  • 两个输入框和按钮的 minimumHeight 均设置为 50(元素在布局管理器中无法直接设置 width 和 height,使用 minimumWidth 和 minimumHeight 代替,此时垂直方向的 sizePolicy 要设为 fixed)。

  • 右键 QCheckBox,选择 Layout Alignment 可以设置 checkbox 的对齐方式(左对齐,居中对齐,右对齐)。

B. 设置背景图片

  • 把上述控件添加一个父元素 QFrame,并设置 QFrame 和窗口一样大。

  • 顶层窗口的 QWidget 无法设置背景图片,因此我们可以再套上一层 QFrame,背景图片就设置到 QFrame 上即可。

创建 resource.qrc,并导入图片:

编写 QSS 样式:

  • 使用 border-image 设置背景图片,而不是 background-image。
  • 主要是因为 border-image 是可以自动缩放的,这一点在窗口大小发生改变时是非常有意义的。
QFrame{
   border-image:url(:/537.jpg);
}

效果:

C. 编写 CSS 代码:

设置 checkbox 样式

  • 背景色使用 transparent 表示完全透明(应用父元素的背景)。
QFrame {
    border-image: url(:/537.jpg);
}

QLineEdit {
    color: #8d98a1;
    background-color: #405361;
    padding: 0 5px;
    font-size: 20px;
    border-style: none;
    border-radius: 10px;
}

QCheckBox {
    color: white;
    background-color: transparent;
}

QPushButton {
    font-size: 20px;
    color: white;
    background-color: #5555;
    border-style: outset;
    border-radius: 10px;
}

QPushButton:pressed {
    color: black;
    background-color: #ced1db;
    border-style: inset;
}

运行程序效果:

最终完整样式代码,这些代码设置到 QFrame 的属性中即可。

通常我们建议把样式代码集中放置,方便调整和排查。


3、小结

QSS 本身给 Qt 提供了更丰富的样式设置的能力,但是整体来说 QSS 的功能是不如 CSS 的。

  • 在 CSS 中,整个网页的样式都是 CSS 一手负责,CSS 功能更强大,并且也更可控。
  • 相比之下,Qt 中是以原生 API 为主,来控制控件之间的尺寸、位置等,QSS 只是起到辅助的作用。
  • 而且 Qt 中提供的一些 “组合控件”(像 QComboBox、QSpinBox 等)内部的结构是不透明的,此时进行一些样式设置也会存在一定的局限性。

另外,做出好看的界面,光靠 QSS 是不够的,更重要的是需要专业美工做出设计稿。


原文地址:https://blog.csdn.net/2301_80171004/article/details/145211023

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!