PySide6从0开始学习的笔记(二) 控件(Widget)之容器类控件

一、控件(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 实例都可以作为父控件,承载其他子控件,并通过布局管理器组织子控件的位置。

  • 核心特性:
  1. 纯空白,可自定义背景、边框等;
  2. 支持布局嵌套;
  3. 可作为独立窗口或子容器使用。
python 复制代码
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中放置控件:

python 复制代码
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,核心扩展是内置边框样式,适合需要视觉分隔的容器场景(如分组、分隔区域)。

  • 核心特性:
  1. 支持多种边框样式(如矩形、阴影、线条);
  2. 可设置边框宽度、颜色、阴影效果;
  3. 完全兼容 QWidget 的容器能力。

常用边框样式(QFrame.Shape)

样式常量 说明
QFrame.NoFrame 无边框(默认)
QFrame.Box 矩形边框(带背景)
QFrame.HLine/VLine 水平 / 垂直线(分隔线)
QFrame.Panel 面板样式(凸起 / 凹陷)
python 复制代码
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 是专为逻辑分组设计的容器,自带可自定义的标题,支持折叠 / 展开(可选),适合将相关控件归类(如表单分组、功能模块分组)。

  • 核心特性:
  1. 显示分组标题(可设置对齐方式);
  2. 支持勾选框(setCheckable(True)),勾选时才启用组内控件;
  3. 视觉上有明显的分组边框。
python 复制代码
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)分隔不同功能模块,适合界面功能较多、需要分页面展示的场景(如软件设置界面、多模块工具)。

  • 核心特性:
  1. 可添加多个标签页,每个标签页对应一个 QWidget 容器;
  2. 支持自定义标签文本、图标、关闭按钮;
  3. 可设置标签位置(上 / 下 / 左 / 右);
  4. 支持标签页切换信号(currentChanged)。
python 复制代码
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 会自动显示滚动条,适合展示长列表、大表单、大图片等场景。

  • 核心特性
  1. 可以自动生成水平 / 垂直滚动条(按需显示);
  2. 可设置滚动条策略(始终显示 / 始终隐藏 / 按需);
  3. 子控件需通过 setWidget() 绑定。
python 复制代码
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 是不可见的分页容器(无标签页),同一时间只显示一个子控件(页面),适合通过按钮 / 下拉框手动切换页面的场景(如向导界面、步骤式操作)。

  • 核心特性
  1. 子控件以 "堆叠" 方式存放,仅显示当前索引的页面;
  2. 轻量级(无标签栏,节省界面空间);
  3. 支持通过 setCurrentIndex() 或 setCurrentWidget() 切换页面;
  4. 触发 currentChanged 信号。
python 复制代码
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 界面的结构化和易用性,结合布局管理器能实现灵活、自适应的界面布局。

相关推荐
_李小白4 小时前
【Android GLSurfaceView源码学习】第二天:GLSurfaceView深度分析
android·学习
摇滚侠5 小时前
Redis 零基础到进阶,Spring Boot 整合 Redis,笔记93-99
spring boot·redis·笔记
秋深枫叶红5 小时前
嵌入式第三十七篇——linux系统编程——线程控制
linux·学习·线程·系统编程
猫天意5 小时前
【即插即用模块】AAAI2025 | 高频 + 空间感知!新 HS-FPN 让“极小目标”不再消失!SCI保二区争一区!彻底疯狂!!!
网络·人工智能·深度学习·学习·音视频
Voyager_45 小时前
算法学习记录17——力扣“股票系列题型”
学习·算法·leetcode
XFF不秃头5 小时前
【力扣刷题笔记-在排序数组中查找元素的第一个和最后一个位置】
c++·笔记·算法·leetcode
正经教主5 小时前
【Trae+AI】和Trae学习搭建App_2.1:第3章·手搓后端基础框架Express
人工智能·后端·学习·express
L.fountain5 小时前
图像自回归生成(Auto-regressive image generation)实战学习(二)
学习·数据挖掘·回归
自不量力的A同学5 小时前
VonaJS 5.0.242 实现了文件级别精确 HMR
笔记