在 Qt Quick Controls 里,容器组件负责把界面元素组织成有视觉边界的块。容器的主要作用是让界面层级更加清晰,这篇先介绍较为基础的三个容器:Pane、Frame、GroupBox。它们看起来都是“一个框”,但默认样式和语义各不相同。
Pane 是基础容器,只提供默认背景和内边距,视觉效果最弱;Frame 继承自 Pane,默认带边框,适合需要明确边界的分组;GroupBox 是带标题的分组框,适合表单、设置项这类需要标题说明的场景。
这三个组件都不强制内部布局,需要自己套 ColumnLayout、RowLayout 或 GridLayout。了解它们的差异后,可以少写很多自定义 Rectangle。
Pane 容器
Pane 是 Qt Quick Controls 里最轻量的容器。它本身不带边框、不带标题,只提供背景色和内边距。默认背景会跟随应用主题变化,所以它在浅色和深色主题下都能自动适配。
它的样式比较朴素,适合作为内容衬底:比如设置页面里的单块区域、卡片式布局的底层、或者任何需要统一内边距但不需要强调边界的场景。如果你只是想给一段内容“垫个底”,Pane 是最合适的选择。
演示代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
FadeInAnimation {
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 20
Layout.rightMargin: 20
spacing: 15
Pane {
Layout.fillWidth: true
Layout.preferredHeight: 120
padding: 15
Label {
anchors.fill: parent
text: "- 默认背景色与应用主题匹配\n- 不提供布局,需自行创建\n- 支持自定义背景\n- 适合作为内容容器"
font.pointSize: 10
textFormat: Text.MarkdownText
wrapMode: Text.WordWrap
}
}
}
Item { Layout.fillHeight: true }
}
}
关键逻辑解析
代码里的 Pane 只做了两件事:设置尺寸、设置 padding。它没有定义内部布局,所以内部套了一个 ColumnLayout 来放 Label。
Pane 的几个特点:
- 不提供布局:Pane 本身不会帮你排布子元素,必须自己套 Layout
- 默认背景跟随主题:背景色由当前控件风格决定,换主题时会自动变
- 内边距可控:通过
padding、leftPadding、rightPadding等属性控制 - 可完全自定义背景:重写
background属性就能换成圆角、阴影、渐变等任意样式
什么时候用 Pane?当你只是想把一段内容包起来、给个内边距和背景,但又不想让它看起来太“重”的时候。
Frame 容器
Frame 和 Pane 几乎一样,但默认多了边框。它继承自 Pane,所以 Pane 有的属性它都有。如果你需要给内容块加一条清晰的边界,Frame 是最省事的方案:不需要手动写 Rectangle 画边框,也不需要调阴影。
Frame 的边框样式同样由当前控件风格决定。在 Basic 风格下,它是一条简洁的细线;在 Fusion 或 Universal 风格下,会有不同的立体或扁平效果。如果你想快速得到一个“有边界的内容块”,直接用 Frame 比自定义 Rectangle 更快。
演示代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
FadeInAnimation {
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 20
Layout.rightMargin: 20
spacing: 15
Frame {
Layout.fillWidth: true
Layout.preferredHeight: 120
padding: 15
Label {
anchors.fill: parent
text: "- 自带边框样式\n- 适合分组显示内容\n- 支持自定义背景\n- 适合作为内容容器"
font.pointSize: 10
textFormat: Text.MarkdownText
wrapMode: Text.WordWrap
}
}
}
Item { Layout.fillHeight: true }
}
}
关键逻辑解析
Frame 与 Pane 的核心差异只有一点:默认视觉层级。
| 特性 | Pane | Frame |
|---|---|---|
| 默认背景 | 有 | 有 |
| 默认边框 | 无 | 有 |
| 继承关系 | Control | 继承 Pane |
| 适用场景 | 衬底、卡片 | 分组、带边界的内容块 |
因为 Frame 继承自 Pane,你也可以重写 background 把边框改成虚线、圆角或渐变。但如果只是想快速分组,默认样式已经够用。
GroupBox 容器
GroupBox 是这三个里相对复杂的一个。它不仅有边框,还有标题栏。在表单页面里,它是最常见的分组方式:把“账号信息”、“网络设置”、“通知偏好”各自放进一个 GroupBox,用户一眼就能看懂字段之间的逻辑关系。
GroupBox 的标题通过 title 属性设置,标题栏会显示在内容上方。内容区域的内边距由 padding 系列属性控制。和 Frame 一样,它也继承自 Pane,所以自定义背景的方式相同。
演示代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
FadeInAnimation {
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 20
Layout.rightMargin: 20
spacing: 15
GroupBox {
title: "GroupBox容器"
Layout.fillWidth: true
Layout.preferredHeight: 120
Label {
anchors.fill: parent
text: "- 带有标题的分组框\n- 适合组织相关控件"
font.pointSize: 10
textFormat: Text.MarkdownText
wrapMode: Text.WordWrap
}
}
}
Item { Layout.fillHeight: true }
}
}
关键逻辑解析
title属性同时控制标题文字和标题栏的显示。如果为空字符串,标题栏会隐藏- 内容区域在标题下方,默认有合理的内边距
- 适合包裹一组语义相关的控件,比如账号设置、网络配置、外观选项
一个常见误区是:GroupBox 本身不限制内部只能放一种控件。你可以放 ColumnLayout、GridLayout、Repeater,甚至是另一个 GroupBox。只要逻辑上属于同一组,就可以放进去。
对比表格
| 容器 | 默认边框 | 标题 | 视觉权重 | 最适合的场景 |
|---|---|---|---|---|
| Pane | 无 | 无 | 低 | 内容卡片、衬底、需要主题适配的背景 |
| Frame | 有 | 无 | 中 | 分组显示、带边框的内容块 |
| GroupBox | 有 | 有 | 高 | 表单分组、设置项集合、需要标题说明的区域 |
选型建议:先试试 Pane,如果边界不够清晰就换 Frame,如果还需要标题说明就换 GroupBox。
运行验证
- Qt Creator 打开
qml_container/CMakeLists.txt - 按
Ctrl+R运行 - 左侧导航切换 “Pane”、“Frame”、“GroupBox” 查看效果
- 尝试修改
padding或重写background,观察容器外观变化
扩展复用方向
- 把 Pane 的背景改成圆角矩形,做成可复用的 Card 组件
- 用 Frame 包裹一组
RadioButton或CheckBox,形成单选/多选分组 - GroupBox 里加
GridLayout做两列表单布局 - 给 Frame/GroupBox 换背景色,匹配深色主题或品牌色
- 把常用的 GroupBox 样式抽成一个自定义组件,避免每个页面都重写 background
已验证环境:
- Qt 版本:Qt 6.11.1
- 操作系统:Windows 11
- GitHub:QML-Minimal-Demos/qml_container