QT开发---QT布局与QSS样式设置
QT布局介绍
在 Qt 中,布局(Layout)是管理界面控件位置和大小的重要机制,能够使界面在窗口大小改变时自动调整控件的布局,确保界面美观且具有良好的适应性。Qt 提供了多种布局管理器,适用于不同的界面需求。
常用布局管理器
Qt布局功能的实现基类为QLayout,为满足不同场景,派生出几种常用的 Qt 布局管理器:
QHBoxLayout : 水平布局管理器,将窗口部件按水平顺序排列。
QVBoxLayout : 垂直布局管理器,将窗口部件按垂直顺序排列。
QGridLayout : 网格布局管理器,按照网格(行列)方式来管理窗口部件,类似于HTML中的表格布局。
QFormLayout : 用于创建两列的表单布局,左列通常为标签,右列为输入控件或其他小部件。
QStackedLayout : 栈式布局,允许切换不同的页面,每个页面占据整个屏幕空间。仅有一个页面是可见的,一次只显示一个控件,类似选项卡效果。
基本使用步骤
- 创建布局对象
- 向布局中添加控件或子布局
- 将布局设置到容器(如 QWidget、QDialog 等)上
#include <QApplication>
#include <QWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include "mainwindow.h"
int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;window.setWindowTitle("Qt布局示例");//创建中心部件,作为布局的容器QWidget *centralWidget = new QWidget(&window);window.setCentralWidget(centralWidget);//主布局(垂直布局),父对象设为中心部件QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);//顶部标题(水平居中)QLabel *titleLabel = new QLabel("用户信息");titleLabel->setAlignment(Qt::AlignCenter);mainLayout->addWidget(titleLabel);//表单部分(网格布局)QGridLayout *formLayout = new QGridLayout;//行0:标签和输入框formLayout->addWidget(new QLabel("用户名:"), 0, 0);formLayout->addWidget(new QLineEdit, 0, 1);//行1:标签和输入框formLayout->addWidget(new QLabel("密码:"), 1, 0);formLayout->addWidget(new QLineEdit, 1, 1);//将网格布局添加到主布局mainLayout->addLayout(formLayout);//按钮区域(水平布局)QHBoxLayout *buttonLayout = new QHBoxLayout;buttonLayout->addWidget(new QPushButton("登录"));buttonLayout->addWidget(new QPushButton("取消"));//将水平布局添加到主布局mainLayout->addLayout(buttonLayout);//调整窗口大小并显示window.resize(300, 200);window.show();return app.exec();
}
布局常用参数设置
在 Qt 布局管理中,通过设置各种参数可以精确控制界面组件的排列、间距、大小适应等行为。
边距(Margins)
控制布局边缘与容器(如 QWidget)之间的空白区域
- 默认情况下,布局会有一定的边距(通常为 11 像素左右)
- 边距过大会导致界面空旷,过小可能让组件贴近窗口边缘
void setContentsMargins(int left, int top, int right, int bottom);
void setContentsMargins(const QMargins &margins);
left 左边缘与容器的距离 ≥0(像素) 通常 11 像素
top 上边缘与容器的距离 同上
right 右边缘与容器的距离 同上
bottom 下边缘与容器的距离 同上
margins QMargins 封装了四边距的对象注:
负值会被自动忽略(视为 0)
嵌套布局时,子布局的边距会叠加到父布局中(eg:父布局左距 10,子布局左距 5,实际总左距 15)
可通过contentsMargins().left()等方法单独获取某一边距
间距(Spacing)
控制布局中相邻组件之间的距离
- 不同布局的默认间距不同(通常为 6-10 像素)
- 水平布局(QHBoxLayout)控制水平方向间距,垂直布局(QVBoxLayout)控制垂直方向间距
- 网格布局(QGridLayout)中,
setHorizontalSpacing()
和setVerticalSpacing()
可分别设置水平和垂直间距
通用布局(QHBoxLayout/QVBoxLayout/QFormLayout)
void setSpacing(int spacing);
spacing 相邻组件之间的距离 ≥0(像素) 通常 6-10 像素网格布局(QGridLayout)专用
void setHorizontalSpacing(int spacing); //列之间的水平间距
void setVerticalSpacing(int spacing); //行之间的垂直间距注:
间距为 0 时组件会紧贴在一起
网格布局中若未单独设置,setSpacing()会同时影响水平和垂直间距
对齐方式(Alignment)
控制组件在其分配的空间内的对齐方式,添加组件时可指定
Qt::AlignLeft 水平左对齐
Qt::AlignRight 水平右对齐
Qt::AlignHCenter 水平居中
Qt::AlignTop 垂直顶部对齐
Qt::AlignBottom 垂直底部对齐
Qt::AlignVCenter 垂直居中
Qt::AlignCenter 水平 + 垂直居中(组合标志) 注:
对齐标志可通过|运算符组合(如Qt::AlignRight | Qt::AlignBottom)
仅当组件尺寸小于分配的空间时,对齐才会生效(组件空间足够时无效果)
伸缩因子(Stretch)
控制组件在布局中的拉伸比例,决定窗口大小变化时组件如何分配额外空间
添加组件 / 布局时指定伸缩因子
void addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment());
void addLayout(QLayout *layout, int stretch = 0);
widget 要添加的组件
layout 要添加的子布局
stretch 伸缩因子(空间分配比例)
alignment 组件在分配空间内的对齐方式
组件大小策略(Size Policy)
组件自身的sizePolicy
属性决定了它在布局中如何响应大小变化
void setSizePolicy(QSizePolicy policy);
void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical);
QSizePolicy::Policy 参数取值:
QSizePolicy::Fixed 大小固定为sizeHint(),不随布局变化
QSizePolicy::Minimum 最小为sizeHint(),可随布局扩大(不小于该值)
QSizePolicy::Maximum 最大为sizeHint(),可随布局缩小(不大于该值)
QSizePolicy::Preferred 优先使用sizeHint(),可扩大或缩小(默认值)
QSizePolicy::Expanding 尽可能布局空间充足时,尽可能占据更多空间
QSizePolicy::MinimumExpanding 不小于sizeHint(),且优先扩展
每个Qt控件都有一个推荐的大小,称为sizeHint()注:
水平和垂直方向可独立设置(如水平Expanding+ 垂直Fixed)
sizeHint()是组件的 "理想大小"(如按钮的理想大小由文本长度决定)
大小策略会与setMinimumSize()/setMaximumSize()结合生效(后者优先级更高)
最小 / 最大尺寸限制
为布局或组件设置尺寸范围,限制其拉伸边界
// 组件/窗口通用
void setMinimumSize(int w, int h);
void setMaximumSize(int w, int h);
void setFixedSize(int w, int h); // 等价于min=max=w/h
w 宽度限制(最小 / 最大) ≥0(像素) 0 表示不限制(但受布局和父容器约束)
h 高度限制(最小 / 最大) ≥0(像素) 固定尺寸时,w和h需同时设置为相同值注:
setFixedSize(w, h) 等价于同时设置 setMinimumSize(w, h) 和 setMaximumSize(w, h)
窗口的最小尺寸建议不小于内容的sizeHint(),否则可能导致内容被截断
组件的尺寸限制会覆盖其sizePolicy的默认行为(如Fixed策略 +setMinimumSize会以限制为准)
占位符(SpacerItem)
通过QSpacerItem
添加空白区域,用于分隔组件或强制对齐
QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum);w 占位符的初始宽度 ≥0(像素)
h 占位符的初始高度 ≥0(像素)
hPolicy 水平方向大小策略 同大小策略取值
vPolicy 垂直方向大小策略 同大小策略取值常用组合示例组合方式 效果描述 适用场景
(20, 20, Expanding, Minimum) 水平可扩展,垂直固定尺寸 将按钮推到右侧
(20, 30, Minimum, Fixed) 水平固定,垂直固定高度(留白) 组件间固定间隔
(0, 0, Expanding, Expanding) 水平和垂直都可扩展(填充剩余空间) 居中布局的空白填充
分裂器布局( QSplitter )
QSplitter
(分裂器布局)是 Qt 中一种特殊的布局组件,允许用户通过拖动分隔条来动态调整子组件的大小,非常适合需要灵活分配空间的场景(如代码编辑器的编辑区与侧边栏、多面板工具界面等)。
与传统布局管理器不同,QSplitter
本身是一个容器组件,而非纯布局管理器,它直接管理子组件并提供交互功能。
QSplitter 的核心特性
- 支持水平(默认)或垂直方向排列子组件
- 用户可通过拖动分隔条调整子组件大小
- 可设置子组件的最小 / 最大尺寸限制
- 支持保存和恢复分隔条位置
- 可嵌套使用(创建复杂的分割布局)
//构造函数
QSplitter(QWidget *parent = nullptr);
QSplitter(Qt::Orientation orientation, QWidget *parent = nullptr);
orientation 分裂器方向(水平 / 垂直) Qt::Vertical(垂直)默认值:Qt::Horizontal(水平) //设置方向
void setOrientation(Qt::Orientation orientation);
Qt::Orientation orientation() const; //获取当前方向
Qt::Horizontal:子组件水平排列(左右分隔条垂直)
Qt::Vertical:子组件垂直排列(分隔条水平) //添加 / 管理子组件
void addWidget(QWidget *widget);----组件会自动成为分裂器的子对象 //插入子组件
void insertWidget(int index, QWidget *widget);
index 插入位置索引(0 为第一个位置) 超出范围则插入到末尾
widget 要插入的子组件----组件会自动成为分裂器的子对象 //移除子组件
void removeWidget(QWidget *widget);---移除后需手动管理组件生命周期//获取子组件列表
QList<QWidget*> widgets() const;
//遍历所有子组件
for (QWidget *w : splitter->widgets())
{qDebug() << "子组件:" << w->objectName();
}//设置子组件大小
void setSizes(const QList<int> &sizes);----列表长度需与子组件数量一致,否则无效
QList<int> sizes() const; //获取当前大小
sizes 子组件尺寸列表(宽度 / 高度,取决于方向)//设置最小尺寸限制----拖动分隔条时,子组件不会小于其最小尺寸
QSplitter 本身不直接提供最小尺寸设置,需通过子组件自身的方法
setMinimumWidth() / setMinimumHeight()//均等分配空间
void setChildrenCollapsible(bool collapse);
bool childrenCollapsible() const;
collapse 是否允许子组件被压缩至 0 尺寸 默认值:true//设置分隔条(Handle)宽度
void setHandleWidth(int width);
int handleWidth() const;
width 分隔条的像素宽度//获取分隔条对象
QSplitterHandle *handle(int index) const;
index 分隔条索引(0 开始) 数量 = 子组件数量 - 1,超出范围返回nullptr//保存布局状态
QByteArray saveState() const;
返回值:包含分隔条位置信息的二进制数据,可持久化存储(如写入配置文件)//恢复布局状态
bool restoreState(const QByteArray &state);
state 保存的布局状态数据 //实时更新开关
void setOpaqueResize(bool opaque);
bool opaqueResize() const;
opaque 拖动时是否实时更新子组件大小 默认值:true
注:
true(默认):拖动时实时调整,视觉流畅但可能卡顿
false:拖动时显示虚线预览,释放后才更新,适合复杂界面//索引转换
int indexOf(QWidget *widget) const; //获取组件在分裂器中的索引
QSS样式设置
QSS(Qt Style Sheets)是 Qt 框架提供的一种强大的样式定制机制,允许开发者通过类似 CSS 的语法自定义控件外观。它借鉴了 CSS 的思想,只不过QSS的功能比CSS要弱很多,主要体现在选择器要少,可以使用的QSS属性也要少很多,但专为 Qt 控件体系设计,提供了针对 Qt 组件的样式控制能力。
QSS 基础架构
QSS 的核心是样式规则,每条规则由选择器和声明块组成,格式如下:
选择器 {属性1: 值1;属性2: 值2;...
}
- 选择器:定位需要应用样式的控件
- 声明块:定义控件的外观属性(如颜色、字体、边框等)
常用选择器
QSS 提供多种选择器,用于精确匹配目标控件:
选择器类型 | 语法示例 | 匹配规则 |
---|---|---|
类型选择器 | QPushButton { ... } | 匹配所有QPushButton 及其子类控件(如自定义的MyButton ) |
类选择器 | .QPushButton { ... } | 仅匹配QPushButton 本身,不包括子类 |
ID 选择器 | QPushButton#submitBtn { ... } | 匹配objectName 为submitBtn 的QPushButton (需先用setObjectName() 设置) |
属性选择器 | QLineEdit[readOnly="true"] { ... } | 匹配readOnly 属性为true 的QLineEdit |
状态选择器 | QPushButton:hover { ... } | 匹配处于hover (鼠标悬停)状态的QPushButton |
后代选择器 | QDialog QPushButton { ... } | 匹配QDialog 所有后代(包括子、孙等)QPushButton |
子选择器 | QWidget > QPushButton { ... } | 仅匹配QWidget 的直接子QPushButton (不包括孙辈) |
通配符 | * { ... } | 匹配所有控件 |
控件状态样式
QSS 支持为控件的不同状态设置差异化样式,常用状态:
状态选择器 | 适用控件 | 说明 |
---|---|---|
:hover | 大部分交互控件 | 鼠标悬停时 |
:pressed | 按钮、复选框等 | 鼠标按下时 |
:checked | 复选框、单选框等 | 被选中时 |
:disabled | 所有控件 | 禁用状态时 |
:focus | 输入控件等 | 获得焦点时 |
:read-only | 输入控件 | 只读状态时 |
:on /:off | 开关控件 | 开关状态(如QSwitch ) |
选择器优先级
当多个规则匹配同一控件时,优先级按以下顺序判定(从高到低):
- 状态选择器
- ID 选择器
- 属性选择器
- 类选择器
- 类型选择器
- 通配符
常用属性分类
QSS 属性针对 Qt 控件特性设计
文本与字体属性
color
- 作用:设置控件文本的颜色
- 取值:
- 颜色名称:
red
、blue
、green
等(支持 CSS 标准颜色名)- RGB 值
- RGBA 值:
(255, 0, 0, 0.5)
(最后一位为透明度,0-1)- 十六进制:
#ff0000
(简写#f00
)、#ff000080
(带透明度)仅对支持文本的控件有效(如
QLabel
、QPushButton
、QLineEdit
)
font-family
- 作用:设置文本字体(字体系列)
- 取值:字体名称,多个字体用逗号分隔(优先使用前面的字体)
中文字体需确保系统中存在(如 Windows 的 "微软雅黑"、Linux 的 "文泉驿")
无衬线字体
sans-serif
可作为 fallback(后备)选项
font-size
- 作用:设置字体大小
- 取值:带单位的数值
px
:像素(屏幕适配友好,推荐)pt
:点(1pt = 1/72 英寸,印刷常用)em
:相对父元素字体大小的倍数
font-weight
- 作用:设置字体粗细(字重)
- 取值:
- 关键字:
normal
(常规,默认)、bold
(粗体)- 数值:100(最细)- 900(最粗),步长 100(400=normal,700=bold)
font-style
- 作用:设置字体样式(倾斜效果)
- 取值:
normal
:正常(默认)italic
:斜体(字体原生倾斜)oblique
:倾斜(强制倾斜变形)
text-align
- 作用:设置文本水平对齐方式
- 取值:
left
(左对齐)、right
(右对齐)、center
(居中)、justify
(两端对齐)仅部分控件支持(如
QLabel
、QPushButton
),QLineEdit
需用alignment
属性
背景样式属性
background-color
- 作用:设置控件的背景颜色
- 取值:同
color
属性(支持 RGB、RGBA、十六进制等)父控件的背景色会被子控件继承(除非子控件单独设置)
background-image
- 作用:设置背景图片
- 取值:
url(图片路径)
,路径支持:
- 资源文件:
url(:/images/bg.png)
(Qt 资源系统路径)- 本地文件:
url(../images/bg.png)
(相对路径)
background-repeat
- 作用:设置背景图片的重复方式(配合
background-image
使用)- 取值:
repeat
:水平和垂直方向重复(默认)repeat-x
:仅水平方向重复repeat-y
:仅垂直方向重复no-repeat
:不重复(只显示一次)
background-position
- 作用:设置背景图片的位置(配合
background-image
和no-repeat
使用)- 取值:
- 关键字:
left
、right
、center
(水平);top
、bottom
(垂直)- 数值:
x y
(如20px 30px
,距离左上角的偏移量)
background-origin
- 作用:设置背景图片的起始绘制位置(相对于控件的哪个区域)
- 取值:
border
:从边框区域开始(包括边框)padding
:从内边距区域开始(不包括边框)content
:从内容区域开始(不包括边框和内边距)
边框样式属性
border
- 作用:简写属性,同时设置边框的宽度、样式和颜色
- 取值:
宽度 样式 颜色
(三个值可省略,按顺序解析)
border-width
- 作用:设置边框宽度(可单独设置某一边)
- 取值:
- 单值:
5px
(四边相同)- 双值:
2px 4px
(上下、左右)- 四值:
1px 2px 3px 4px
(上、右、下、左)- 单边设置:
border-top-width: 2px;
(仅上边框)
border-style
- 作用:设置边框样式(可单独设置某一边)
- 取值:
none
:无边框(默认)solid
:实线dashed
:虚线(短横线)dotted
:点线double
:双线- 单边设置:
border-left-style: dashed;
border-color
- 作用:设置边框颜色(可单独设置某一边)
- 取值:同
color
属性,支持多值(规则同border-width
)
border-radius
- 作用:设置边框圆角半径(实现圆角控件)
- 取值:像素值,或水平 / 垂直半径(
x y
)结合
background-color
可实现圆角按钮 / 输入框,过大的半径可能导致显示异常
内边距与外边距属性
内边距(Padding)
内边距是指元素内容与元素边框之间的空间。它控制着元素内部内容与边界的距离,直接影响元素的可视内容和视觉效果。
外边距(Margin)
外边距是指元素边框与其他元素之间的空间。它控制着元素与周围元素的距离,影响页面布局的整体结构。
padding
- 作用:设置控件内容与边框之间的距离(内边距)
- 取值:
- 单值:
5px
(四边相同)- 双值:
3px 6px
(上下、左右)- 四值:
2px 4px 6px 8px
(上、右、下、左)- 单边设置:
padding-top: 10px;
margin
- 作用:设置控件与相邻控件之间的距离(外边距)
- 取值:规则同
padding
尺寸与定位
width
/height
- 作用:固定控件的宽度 / 高度
- 取值:像素值(
px
)或百分比(相对于父控件)优先级高于布局管理器的默认尺寸,可能导致布局异常
min-width
/max-width
- 作用:限制控件的最小 / 最大宽度
min-height
/max-height
- 作用:限制控件的最小 / 最大高度
- 取值:像素值
qproperty-xxx
核心原理
xxx
对应控件的属性名(必须是控件类中声明的 Q_PROPERTY)- 通过 QSS 直接设置这些属性,等价于在代码中调用
setXxx()
方法 - 支持几乎所有 Qt 控件的可写属性(如
text
、icon
、checked
等)
选择器 {qproperty-属性名: 属性值;
}
属性名:必须与控件类中声明的 Q_PROPERTY 名称完全一致(区分大小写)
属性值:需符合该属性的类型要求(如字符串、数值、布尔值、枚举等)
结语:
无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力