[Qt] Box Model | 控件样式 | 实现log_in界面
目录
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 | 子控件选择器。 |
:hover | 伪类选择器。 |
:pressed | 伪类选择器。 |
:checked | 伪类选择器。 |
:unchecked | 伪类选择器。 |
width | 设置子控件宽度。 |
height | 设置子控件高度。 |
image | 设置子控件的图片。 |
(3)单选框
【自定义单选框】
A. 创建 resource.qrc 文件,并导入以下图片
- 使用黑色作为默认形态
- 使用蓝色作为 hover 形态
- 使用红色作为 pressed 形态
注意这里的文件命名。
B. 在界面上创建两个单选按钮
要点 | 说明 |
::indicator | 子控件选择器。 |
:hover | 伪类选择器。 |
:pressed | 伪类选择器。 |
:checked | 伪类选择器。 |
:unchecked | 伪类选择器。 |
width | 设置子控件宽度。 |
height | 设置子控件高度。 |
image | 设置子控件的图片。 |
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 | 选中 |
: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)!