python pyside2 Frame容器(QFrame)

介绍

在 PySide2(Qt for Python)GUI 开发中,QFrame 是一个兼具 容器功能 与 装饰特性 的基础控件 —— 它不仅能作为子控件的载体(类似 QWidget),还支持自定义边框、背景色、阴影等样式,常用于界面分区、控件分组或视觉装饰。本文将从核心特性、样式定制、功能扩展及实战案例,系统讲解 QFrame 的使用方法。

应用场景

  • 控件分组:将相关控件(如登录表单的 “账号 + 密码”)包裹在 QFrame 中,通过边框 / 背景区分区域;

  • 界面分区:在复杂界面中用 QFrame 划分功能模块(如左侧导航区、中间内容区、右侧信息区);

  • 视觉装饰:作为分隔线、卡片容器或带阴影的面板,提升界面美观度;

  • 自定义控件基类:基于 QFrame 扩展带边框 / 背景的自定义控件(如进度条、仪表盘)。

frameStyle(边框样式)

QFrame 最核心的特性是通过 frameStyle 控制边框类型,该属性由 “边框形状” 和 “边框阴影” 两部分组成,通过按位或(|)组合使用。

边框形状(Shape)

常量 含义 适用场景
QFrame.NoFrame 无边框(默认) 仅作为透明容器
QFrame.Box 矩形边框 控件分组、卡片容器
QFrame.HLine 水平分隔线(仅显示水平边框) 界面模块间的水平分隔
QFrame.VLine 垂直分隔线(仅显示垂直边框) 界面模块间的垂直分隔
QFrame.Panel 面板边框(带凹陷 / 凸起效果) 按钮面板、信息展示区

边框阴影(Shadow)

常量 含义 视觉效果
QFrame.Plain 无阴影(平面边框) 简洁风格界面
QFrame.Sunken 凹陷阴影(边框向内凹陷) 需强调 “可交互” 的区域
QFrame.Raised 凸起阴影(边框向外凸起) 需突出 “当前选中” 的区域

基础示例:组合边框样式

from PySide2.QtWidgets import QApplication, QWidget, QVBoxLayout, QFrame, QLabel

import sys

app = QApplication(sys.argv)

window = QWidget()

window.setWindowTitle("QFrame 边框样式示例")

window.resize(400, 300)

main\_layout = QVBoxLayout(window)

main\_layout.setSpacing(20)

main\_layout.setContentsMargins(20, 20, 20, 20)

\# 1. 矩形边框(Box + Raised):控件分组

frame1 = QFrame()

frame1.setFrameStyle(QFrame.Box | QFrame.Raised)  # 矩形边框 + 凸起阴影

frame1.setLineWidth(2)  # 边框宽度(默认 1px)

\# 向 frame1 中添加控件(需先设置布局)

frame1\_layout = QVBoxLayout(frame1)

frame1\_layout.addWidget(QLabel("这是带凸起边框的分组容器"))

frame1\_layout.addWidget(QLabel("适合包裹相关控件,区分功能区域"))

main\_layout.addWidget(frame1)

\# 2. 水平分隔线(HLine + Plain):模块分隔

frame2 = QFrame()

frame2.setFrameStyle(QFrame.HLine | QFrame.Plain)  # 水平分隔线 + 无阴影

frame2.setLineWidth(1)

main\_layout.addWidget(frame2)

\# 3. 面板边框(Panel + Sunken):信息展示

frame3 = QFrame()

frame3.setFrameStyle(QFrame.Panel | QFrame.Sunken)  # 面板边框 + 凹陷阴影

frame3.setMidLineWidth(3)  # 中间线宽度(增强凹陷效果,仅 Panel 样式生效)

frame3\_layout = QVBoxLayout(frame3)

frame3\_layout.addWidget(QLabel("这是带凹陷效果的面板"))

frame3\_layout.addWidget(QLabel("适合展示重要信息,视觉上更突出"))

main\_layout.addWidget(frame3)

window.show()

sys.exit(app.exec\_())

关键方法说明:

  • setFrameStyle(style):设置边框样式(形状 + 阴影,需用 | 组合);

  • setLineWidth(width):设置边框外线宽度(默认 1px,所有边框样式生效);

  • setMidLineWidth(width):设置边框中间线宽度(仅 Panel 样式生效,增强凹陷 / 凸起效果);

  • setFrameRect(rect):手动设置边框区域(默认与控件大小一致,一般无需修改)。

背景色与背景图片

QFrame 支持通过 setStyleSheet 或 setBackgroundRole 定制背景,满足不同界面风格需求。

通过 StyleSheet 设置背景(推荐,灵活度高)

\# 1. 纯色背景 + 圆角边框

frame = QFrame()

frame.setStyleSheet("""

    QFrame {

        background-color: #F0F8FF;  /\* 浅蓝色背景 \*/

        border: 2px solid #4169E1;  /\* 深蓝色边框 \*/

        border-radius: 8px;         /\* 圆角(需与 border 配合使用) \*/

        padding: 15px;              /\* 内边距(避免子控件贴边) \*/

    }

""")

\# 2. 背景图片(拉伸填充)

frame\_with\_img = QFrame()

frame\_with\_img.setFixedSize(300, 200)  # 固定控件大小

frame\_with\_img.setStyleSheet("""

    QFrame {

        background-image: url("background.jpg");  /\* 图片路径(相对/绝对路径) \*/

        background-repeat: no-repeat;  /\* 不重复显示 \*/

        background-size: cover;        /\* 拉伸填充(保持比例,可能裁剪) \*/

        background-position: center;   /\* 图片居中 \*/

        border: 1px solid #CCCCCC;

        border-radius: 4px;

    }

""")

通过 BackgroundRole 设置背景(与系统主题兼容)

setBackgroundRole 基于 Qt 的 “颜色角色”(Color Role)设置背景,颜色会随系统主题变化,适合追求跨平台一致性的场景:

from PySide2.QtGui import QPalette

frame = QFrame()

frame.setFrameStyle(QFrame.Box | QFrame.Plain)

\# 获取系统调色板

palette = frame.palette()

\# 设置背景角色为“窗口背景色”(可替换为其他角色,如 QPalette.Base、QPalette.Highlight)

palette.setColor(QPalette.Background, palette.color(QPalette.Window))

\# 若需自定义颜色,可直接指定 RGB:

\# palette.setColor(QPalette.Background, QColor(240, 248, 255))  # 浅蓝色

frame.setPalette(palette)

frame.setAutoFillBackground(True)  # 必须启用自动填充,否则背景色不生效

颜色角色(Color Role)常用值:

  • QPalette.Window:窗口背景色(系统默认);

  • QPalette.Base:文本输入控件背景色(如 QLineEdit 背景);

  • QPalette.Highlight:选中项背景色(如选中的文本、按钮);

  • QPalette.AlternateBase:交替行背景色(如表格的隔行变色)。

阴影效果(QGraphicsDropShadowEffect)

通过 QGraphicsDropShadowEffect 给 QFrame 添加阴影,提升界面层次感,适合卡片、弹窗等场景:

from PySide2.QtGui import QGraphicsDropShadowEffect

from PySide2.QtCore import QColor

frame = QFrame()

frame.setStyleSheet("""

    QFrame {

        background-color: white;

        border-radius: 10px;

        padding: 20px;

    }

""")

frame.setFixedSize(350, 250)

\# 创建阴影效果

shadow = QGraphicsDropShadowEffect()

shadow.setColor(QColor(0, 0, 0, 30))  # 阴影颜色(RGBA,最后一位是透明度)

shadow.setBlurRadius(15)  # 阴影模糊半径(值越大,阴影越模糊)

shadow.setOffset(0, 5)  # 阴影偏移(x, y,正值表示向右/向下偏移)

\# 给 frame 应用阴影

frame.setGraphicsEffect(shadow)

注意事项:

  • 阴影效果需配合 border-radius 使用(否则阴影会是矩形,与圆角边框不匹配);

  • setBlurRadius 过大会影响性能(建议值不超过 20);

  • 若 QFrame 是顶层控件(无父控件),阴影可能被截断,需确保父容器有足够空间。

与布局结合:作为容器使用

QFrame 本质是 QWidget 的子类,完全支持布局管理 —— 将布局绑定到 QFrame 后,可作为 “带样式的容器” 包裹子控件,实现 “视觉分组 + 自适应排版”。

实战示例:带边框的登录表单(QFrame + QFormLayout)

from PySide2.QtWidgets import QLineEdit, QPushButton, QFormLayout, QCheckBox

app = QApplication(sys.argv)

window = QWidget()

window.setWindowTitle("QFrame 布局容器示例")

window.resize(400, 300)

window.setStyleSheet("background-color: #F5F5F5;")  # 窗口背景色(浅灰)

\# 创建 QFrame 作为表单容器(带阴影和圆角)

form\_frame = QFrame()

form\_frame.setStyleSheet("""

    QFrame {

        background-color: white;

        border: none;

        border-radius: 10px;

        padding: 25px;

    }

""")

\# 添加阴影效果

shadow = QGraphicsDropShadowEffect()

shadow.setColor(QColor(0, 0, 0, 20))

shadow.setBlurRadius(12)

shadow.setOffset(0, 4)

form\_frame.setGraphicsEffect(shadow)

\# 在 QFrame 中设置表单布局

form\_layout = QFormLayout(form\_frame)

form\_layout.setSpacing(20)

form\_layout.setContentsMargins(0, 0, 0, 0)  # 清除布局内边距(依赖 frame 的 padding)

\# 添加表单控件

account\_edit = QLineEdit()

account\_edit.setPlaceholderText("请输入账号")

account\_edit.setStyleSheet("padding: 8px; border: 1px solid #DDDDDD; border-radius: 4px;")

pwd\_edit = QLineEdit()

pwd\_edit.setEchoMode(QLineEdit.Password)

pwd\_edit.setPlaceholderText("请输入密码")

pwd\_edit.setStyleSheet("padding: 8px; border: 1px solid #DDDDDD; border-radius: 4px;")

remember\_box = QCheckBox("记住账号密码")

login\_btn = QPushButton("登录")

login\_btn.setStyleSheet("""

    QPushButton {

        background-color: #2196F3;

        color: white;

        border: none;

        border-radius: 4px;

        padding: 10px;

        font-size: 14px;

    }

    QPushButton:hover {

        background-color: #1976D2;  /\* 鼠标悬浮时加深颜色 \*/

    }

""")

\# 将控件加入布局

form\_layout.addRow(account\_edit)

form\_layout.addRow(pwd\_edit)

form\_layout.addRow(remember\_box)

form\_layout.addRow(login\_btn)

\# 窗口主布局(将 frame 居中显示)

main\_layout = QVBoxLayout(window)

main\_layout.addStretch(1)  # 顶部弹性空白

main\_layout.addWidget(form\_frame, alignment=Qt.AlignCenter)  # 居中显示 frame

main\_layout.addStretch(1)  # 底部弹性空白

main\_layout.setContentsMargins(50, 50, 50, 50)

window.show()

sys.exit(app.exec\_())

效果说明:

  • QFrame 作为表单容器,通过阴影和圆角实现 “卡片式” 视觉效果;

  • 布局绑定在 QFrame 内部,子控件(账号输入框、登录按钮)自适应 QFrame 大小;

  • 窗口主布局通过 addStretch 让 QFrame 垂直居中,提升界面美观度。

QFrame 子类:常用扩展控件

QFrame 是多个常用控件的基类,这些子类继承了 QFrame 的边框和容器特性,并扩展了专属功能:

子类控件 核心功能 继承的 QFrame 特性 适用场景
QPushButton 按钮交互(点击触发事件) 支持边框样式、背景色、阴影 操作触发(登录、提交)
QToolButton 工具按钮(带图标 / 文本) 支持 Panel 边框样式、凸起 / 凹陷效果 工具栏、导航栏按钮
QGroupBox 带标题的分组容器 支持边框样式,内置标题栏 复杂表单的分组(如 “个人信息”“权限设置”)
QSplitter 可拖动的分隔容器(支持多面板) 支持垂直 / 水平分隔线样式 多区域界面(如左侧导航 + 右侧内容)
QScrollArea 带滚动条的容器 支持边框样式,内置滚动功能 内容超出可视区域的场景(如长列表)

示例:QGroupBox(带标题的 QFrame 子类)

group\_box = QGroupBox("个人信息设置")  # 标题

group\_box.setFrameStyle(QFrame.Box | QFrame.Plain)  # 边框样式

group\_box\_layout = QFormLayout(group\_box)

group\_box\_layout.addRow("姓名:", QLineEdit())

group\_box\_layout.addRow("年龄:", QLineEdit())

group\_box\_layout.addRow("性别:", QComboBox())  # 下拉框

常见问题与解决方案

问题:QFrame 边框与圆角不生效

原因:

  • 未设置 border 却单独使用 border-radius(圆角需与边框配合);

  • frameStyle 与 StyleSheet 冲突(frameStyle 会覆盖部分 StyleSheet 边框设置)。

解决方案:

  • 优先通过 StyleSheet 统一设置边框和圆角,避免混合使用 frameStyle;

  • 确保 StyleSheet 中 border 和 border-radius 同时存在:

frame.setStyleSheet("""

    QFrame {

        border: 2px solid #000;  /\* 必须设置 border \*/

        border-radius: 8px;      /\* 圆角才会生效 \*/

    }

""")

问题:背景色不显示

原因:

  • 未启用 setAutoFillBackground(True)(通过 setBackgroundRole 设置背景时);

  • StyleSheet 中 background-color 被父控件样式覆盖;

  • QFrame 有子控件且子控件覆盖了背景(如子控件背景色不透明)。

解决方案:

  • 若用 setBackgroundRole,必须调用 `setAutoFillBackground (True

原文出处:/show_1GW1rI2khhAe.html