一、控件(Widget)基本概念
控件(Widget)本质是 图形界面(GUI)里的 “基础功能组件” —— 就像搭界面的 “乐高积木”,是用户能看见、能操作(或仅展示)的最小单元,不用懂 Qt 底层,记住 3 个核心点即可:
1. 控件的核心作用:“承上启下”
- 对用户:提供交互入口(比如点按钮、输文字)或信息展示(比如看文本、图片);
- 对程序:接收用户操作(比如点击、输入),或呈现程序处理结果(比如显示计算结果)。
2. 常见控件类型
- 容器类:窗口(Window,最外层 “大容器”)、面板(Widget,把多个小控件归为一组等)。
- 交互类:按钮(Button,点一下触发功能)、输入框(Line Edit,输文字 / 数字)、复选框(CheckBox,选 / 不选)、下拉菜单(ComboBox,选列表里的选项)等;
- 展示类:标签(Label,显示文字 / 图片,不能改)、文本框(Text Edit,显示多行文字)、进度条(Progress Bar,展示加载 / 处理进度);
3. 控件的关键特性
- 有 “属性”:比如按钮的文字、大小、颜色,输入框的默认值、是否可编辑;
- 能 “响应事件”:用户操作会触发反应(比如点按钮→程序执行某个功能,输文字→程序接收输入内容);
- 可 “组合嵌套”:比如把按钮、输入框放进一个面板,再把面板放进窗口,搭出复杂界面。
二、容器类控件详解
PySide6 中的容器类控件是用于组织、管理其他子控件的核心组件,它们不仅能承载多个控件,还提供布局管理、分组显示、页面切换等功能。
- 容器类控件核心分类
PySide6 的容器控件主要分为两类:
基础布局容器:以布局管理为核心(如 QWidget、QFrame);
功能型容器:提供分组、分页、滚动等附加功能(如 QGroupBox、QTabWidget、QScrollArea 等)。
-
QWidget(基础万能容器)
QWidget 是所有 PySide6 控件的基类,本身也是最基础的容器 —— 任何 QWidget 实例都可以作为父控件,承载其他子控件,并通过布局管理器组织子控件的位置。
- 核心特性:
- 纯空白,可自定义背景、边框等;
- 支持布局嵌套;
- 可作为独立窗口或子容器使用。
import sys
from PySide6.QtWidgets import QApplication, QWidget
# 定义一个父容器类,作为主窗口
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QWidget 基础容器示例")
self.setStyleSheet("background-color: green;") # 设置容器的显示样式,方便观察
self.resize(300, 200)
# 创建 QWidget 作为子容器
son_container = QWidget(self)
son_container.setGeometry(10, 10, 280, 180) # 设置子容器的几何特征,位置为 (10, 10),大小为 (280, 180)
son_container.setStyleSheet("background-color: red") # 设置容器的显示样式,方便观察
if __name__ == "__main__":
app = QApplication(sys.argv) # 创建 QApplication 对象
main_window = MainWindow() # 创建 MainWindow 实例对象
main_window.show() # 显示窗口
sys.exit(app.exec()) # 退出应用程序

在上面这个实例中,有两个QWidget容器,背景色为绿色的是主窗口main_window,背景色为红色的是主窗口的子容器son_container。
继续,在子容器son_container中放置控件:
import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton
# 定义一个父容器类,作为主窗口
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QWidget 基础容器示例")
self.setStyleSheet("background-color: green;") # 设置容器的显示样式,方便观察
self.resize(300, 200)
# 创建 QWidget 作为子容器
son_container = QWidget(self)
son_container.setGeometry(10, 10, 280, 180) # 设置子容器的几何特征,位置为 (10, 10),大小为 (280, 180)
son_container.setStyleSheet("background-color: red") # 设置容器的显示样式,方便观察
button = QPushButton("子容器的按钮", son_container) # 创建按钮,作为子容器的子控件
button.setStyleSheet("background-color: gray") # 设置按钮的显示样式
button.setGeometry(40, 50, 200, 40) # 设置按钮的几何特征
if __name__ == "__main__":
app = QApplication(sys.argv) # 创建 QApplication 对象
main_window = MainWindow() # 创建 MainWindow 实例对象
main_window.show() # 显示窗口
sys.exit(app.exec()) # 退出应用程序

放置了一个按钮在子容器中。
-
QFrame(带边框的容器)
QFrame 继承自 QWidget,核心扩展是内置边框样式,适合需要视觉分隔的容器场景(如分组、分隔区域)。
- 核心特性:
- 支持多种边框样式(如矩形、阴影、线条);
- 可设置边框宽度、颜色、阴影效果;
- 完全兼容 QWidget 的容器能力。
常用边框样式(QFrame.Shape)
| 样式常量 | 说明 |
|---|---|
QFrame.NoFrame | 无边框(默认) |
QFrame.Box | 矩形边框(带背景) |
QFrame.HLine/VLine | 水平 / 垂直线(分隔线) |
QFrame.Panel | 面板样式(凸起 / 凹陷) |
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QFrame, QPushButton)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QFrame 带边框容器示例")
self.resize(350, 150)
# 创建 QFrame 容器
frame = QFrame(self)
frame.setFrameShape(QFrame.Box) # 矩形边框
frame.setFrameShadow(QFrame.Raised) # 凸起阴影
frame.setLineWidth(2) # 边框宽度
frame.setStyleSheet("background-color: green;") # 背景色
frame.setGeometry(60, 30, 230, 90) # 设置容器位置和大小
# 容器内的控件
button = QPushButton("登录",frame) # 添加按钮
button.setGeometry(80, 30, 70, 30) # 设置按钮位置和大小
button.setStyleSheet("background-color: lightgray;") # 按钮背景色
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

-
QGroupBox(分组容器)
QGroupBox 是专为逻辑分组设计的容器,自带可自定义的标题,支持折叠 / 展开(可选),适合将相关控件归类(如表单分组、功能模块分组)。
- 核心特性:
- 显示分组标题(可设置对齐方式);
- 支持勾选框(setCheckable(True)),勾选时才启用组内控件;
- 视觉上有明显的分组边框。
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QGroupBox,
QVBoxLayout, QRadioButton, QCheckBox, QPushButton, QFrame)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QGroupBox 分组容器示例")
self.resize(400, 400)
# 创建一个QFrame对象作为分组容器的父控件
frame = QFrame(self)
frame.setGeometry(50, 50, 300, 300)
frame.setStyleSheet("QFrame {border: 3px solid green;background-color: blue}")
# 1. 创建分组容器
group = QGroupBox("group群组容器", frame) # group群组容器
group.setGeometry(50, 50, 200, 100) # 设置组容器位置和大小
group.setStyleSheet("QGroupBox {border: 3px solid green;background-color: red};") # 设置组容器背景色
# 2. 群组内的按钮控件
button_1= QPushButton("按钮1", group)
button_2= QPushButton("按钮2", group)
button_1.setGeometry(50, 20, 100, 30)
button_2.setGeometry(50, 60, 100, 30)
# 3. 另一个不属于群组的按钮
button_3 = QPushButton("按钮3", frame)
button_3.setGeometry(100, 200, 100, 30)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

-
QTabWidget(分页容器)
QTabWidget 是多页面切换容器,通过标签页(Tab)分隔不同功能模块,适合界面功能较多、需要分页面展示的场景(如软件设置界面、多模块工具)。
- 核心特性:
- 可添加多个标签页,每个标签页对应一个 QWidget 容器;
- 支持自定义标签文本、图标、关闭按钮;
- 可设置标签位置(上 / 下 / 左 / 右);
- 支持标签页切换信号(currentChanged)。
-
import sys from PySide6.QtWidgets import (QApplication, QWidget, QTabWidget, QLabel) class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QTabWidget 分页容器示例") self.resize(400, 300) # 1. 创建分页容器 tab_widget = QTabWidget(self) tab_widget.setTabPosition(QTabWidget.North) # 标签在顶部(默认) tab_widget.setTabsClosable(False) # 不显示关闭按钮 tab_widget.setGeometry(10, 10, 380, 280) # 2. 页面1 page1 = QWidget() label1 = QLabel("这是页面 1 的内容", page1) label1.setGeometry(50, 50, 100, 50) tab_widget.addTab(page1, "基础设置") # 添加页面,设置标签文本 # 3. 页面2 page2 = QWidget() label2 = QLabel("这是页面 2 ", page2) label2.setGeometry(50, 50, 100, 50) tab_widget.addTab(page2, "高级设置") # 添加页面,设置标签文本 if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
-
QScrollArea(滚动容器)
当子控件内容超出可视区域时,QScrollArea 会自动显示滚动条,适合展示长列表、大表单、大图片等场景。
- 核心特性
- 可以自动生成水平 / 垂直滚动条(按需显示);
- 可设置滚动条策略(始终显示 / 始终隐藏 / 按需);
- 子控件需通过 setWidget() 绑定。
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QScrollArea, QPushButton)
from PySide6.QtCore import Qt
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QScrollArea 滚动容器示例")
self.resize(300, 200)
# 1. 创建滚动容器
scroll_area = QScrollArea(self)
# 设置滚动条策略
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 水平滚动条(按需显示)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 垂直滚动条(按需显示)
scroll_area.setGeometry(0, 0, 150, 150) # 滚动区域大小
# 2. 创建子容器(承载大量控件)
content_widget = QWidget(self)
content_widget.setGeometry(0, 0, 300, 300)
# 3. 添加大量按钮(超出可视区域)
for i in range(20):
btn = QPushButton(f"按钮 {i+1}", content_widget)
btn.setGeometry(0, i * 40, 200, 30)
# 4. 将子容器绑定到滚动区域
scroll_area.setWidget(content_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
-
QStackedWidget(堆叠容器)
QStackedWidget 是不可见的分页容器(无标签页),同一时间只显示一个子控件(页面),适合通过按钮 / 下拉框手动切换页面的场景(如向导界面、步骤式操作)。
- 核心特性
- 子控件以 “堆叠” 方式存放,仅显示当前索引的页面;
- 轻量级(无标签栏,节省界面空间);
- 支持通过 setCurrentIndex() 或 setCurrentWidget() 切换页面;
- 触发 currentChanged 信号。
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QStackedWidget,
QVBoxLayout, QHBoxLayout, QPushButton, QLabel)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QStackedWidget 堆叠容器示例")
self.resize(400, 400)
# 1. 创建堆叠容器
stacked_widget = QStackedWidget(self)
# 2. 创建多个页面
page1 = QLabel("堆叠页面 1 ", self)
page1.setGeometry(50, 0, 300, 200)
page2 = QLabel("堆叠页面 2 ", self)
page2.setGeometry(50, 0, 300, 200)
page3 = QLabel("堆叠页面 3 ", self)
page3.setGeometry(50, 0, 300, 200)
# 3. 添加页面到堆叠容器
stacked_widget.addWidget(page1)
stacked_widget.addWidget(page2)
stacked_widget.addWidget(page3)
# 4. 切换按钮
btn_prev = QPushButton("上一步", self)
btn_prev.setGeometry(100, 200, 100, 50)
btn_next = QPushButton("下一步", self)
btn_next.setGeometry(200, 200, 100, 50)
btn_prev.clicked.connect(lambda: self.switch_page(stacked_widget, -1)) # 连接上一步按钮的点击事件
btn_next.clicked.connect(lambda: self.switch_page(stacked_widget, 1)) # 连接下一步按钮的点击事件
def switch_page(self, stacked, step):
"""切换页面"""
current_idx = stacked.currentIndex()
new_idx = current_idx + step
# 边界检查
if 0 <= new_idx < stacked.count():
stacked.setCurrentIndex(new_idx)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

三、容器控件选型指南
| 容器控件 | 核心场景 | 关键优势 |
|---|---|---|
| QWidget | 通用容器、布局嵌套 | 轻量、万能、无额外样式 |
| QFrame | 带边框的分隔区域 | 内置边框样式、阴影效果 |
| QGroupBox | 逻辑分组、表单归类 | 自带标题、支持勾选启用 |
| QTabWidget | 多标签页切换(可视化) | 直观的标签切换、易操作 |
| QScrollArea | 内容超出可视区域 | 自动滚动、适配长内容 |
| QStackedWidget | 无标签页的页面切换 | 轻量、节省空间、手动控制切换 |
四、核心注意事项
布局绑定:容器的子控件最好通过布局管理器(如 QVBoxLayout)绑定,否则子控件可能无法正 常显示 / 自适应;下一节将会学习布局管理器,并重新编写本节代码。
父子关系:子控件的父对象需设置为容器,或通过布局添加(布局会自动设置父对象),否则控件可能 “丢失”;
样式定制:可通过 setStyleSheet() 自定义容器的背景、边框、间距等样式;
性能优化:对于大量子控件的容器(如 QScrollArea),建议使用 QListView/QTableView 等视图控件(而非手动添加大量按钮 / 标签),提升渲染性能。
通过合理选择容器控件,可大幅提升 GUI 界面的结构化和易用性,结合布局管理器能实现灵活、自适应的界面布局。