QGridLayout
是 PyQt5 中用于将控件按网格(行和列)排列的布局管理器,支持复杂的多行多列布局,适合构建表单、仪表盘等需要精确控制控件位置的场景。以下是详细介绍及常用方法:
一、核心功能
- 网格结构:控件按行(
row
)和列(column
)定位,索引从 0 开始。 - 跨行跨列:允许控件占据多行或多列(通过
rowSpan
和columnSpan
)。 - 动态调整:支持设置行列的拉伸比例(
stretch
),适配窗口缩放。 - 对齐方式:独立控制每个控件的对齐方向(左对齐、居中等)。
- 嵌套布局:可与其他布局(如
QVBoxLayout
)混合使用。
二、常用方法
1. 添加控件
方法 | 说明 | 示例 |
---|---|---|
addWidget(widget, row, column, rowSpan=1, columnSpan=1, alignment=0) | 将控件添加到指定行列 | layout.addWidget(button, 0, 0) |
addLayout(layout, row, column, rowSpan=1, columnSpan=1, alignment=0) | 添加子布局到网格 | layout.addLayout(sub_layout, 1, 0) |
2. 行列配置
方法 | 说明 | 示例 |
---|---|---|
setRowStretch(row, factor) | 设置行的拉伸比例(按比例分配剩余空间) | layout.setRowStretch(0, 1) |
setColumnStretch(column, factor) | 设置列的拉伸比例 | layout.setColumnStretch(1, 2) |
setRowMinimumHeight(row, minHeight) | 设置行的最小高度 | layout.setRowMinimumHeight(0, 50) |
setColumnMinimumWidth(column, minWidth) | 设置列的最小宽度 | layout.setColumnMinimumWidth(0, 100) |
3. 边距与间距
方法 | 说明 | 示例 |
---|---|---|
setContentsMargins(left, top, right, bottom) | 设置布局边距 | layout.setContentsMargins(10, 5, 10, 5) |
setHorizontalSpacing(spacing) | 设置水平间距(列间距) | layout.setHorizontalSpacing(10) |
setVerticalSpacing(spacing) | 设置垂直间距(行间距) | layout.setVerticalSpacing(15) |
4. 其他操作
方法 | 说明 | 示例 |
---|---|---|
itemAtPosition(row, column) -> QLayoutItem | 获取指定位置的布局项 | item = layout.itemAtPosition(0, 0) |
removeWidget(widget) | 移除控件 | layout.removeWidget(button) |
三、代码示例
1. 基础网格布局(表单)
python
from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel, QLineEdit, QPushButton
class Form(QWidget):
def __init__(self):
super().__init__()
layout = QGridLayout(self)
# 标签和输入框(第0行)
layout.addWidget(QLabel("用户名:"), 0, 0)
layout.addWidget(QLineEdit(), 0, 1)
# 密码输入(第1行)
layout.addWidget(QLabel("密码:"), 1, 0)
layout.addWidget(QLineEdit(echoMode=QLineEdit.Password), 1, 1)
# 按钮(第2行,跨两列)
submit_btn = QPushButton("提交")
layout.addWidget(submit_btn, 2, 0, 1, 2) # 跨1行2列
self.setWindowTitle("表单布局")
self.resize(300, 150)
2. 跨行跨列示例
python
class SpanDemo(QWidget):
def __init__(self):
super().__init__()
layout = QGridLayout(self)
# 控件占据多行多列
big_button = QPushButton("跨2行3列")
layout.addWidget(big_button, 0, 0, 2, 3) # 从(0,0)开始,占2行3列
# 其他控件
small_btn1 = QPushButton("按钮1")
small_btn2 = QPushButton("按钮2")
layout.addWidget(small_btn1, 2, 0)
layout.addWidget(small_btn2, 2, 1)
3. 行列拉伸比例
python
class StretchDemo(QWidget):
def __init__(self):
super().__init__()
layout = QGridLayout(self)
# 第0列占1份宽度,第1列占2份宽度
layout.setColumnStretch(0, 1)
layout.setColumnStretch(1, 2)
# 添加控件
layout.addWidget(QPushButton("左侧"), 0, 0)
layout.addWidget(QPushButton("右侧"), 0, 1)
四、常用技巧
1. 控件对齐
python
# 将按钮在网格单元内居中对齐
layout.addWidget(button, 0, 0, alignment=Qt.AlignCenter)
2. 动态添加控件
python
def add_dynamic_widget(self):
new_btn = QPushButton("动态按钮")
self.layout.addWidget(new_btn, self.current_row, 0)
self.current_row += 1
3. 嵌套子布局
python
# 在网格中嵌套垂直布局
sub_layout = QVBoxLayout()
sub_layout.addWidget(QCheckBox("选项1"))
sub_layout.addWidget(QCheckBox("选项2"))
layout.addLayout(sub_layout, 0, 2)
五、注意事项
-
索引越界:
行/列号必须 >= 0,否则会引发错误。未显式设置的行/列默认无拉伸因子。 -
动态调整:
窗口缩放时,通过setRowStretch
和setColumnStretch
控制行列的伸缩比例。 -
性能优化:
避免网格过于复杂(如超过 10x10),可能影响渲染效率。 -
隐藏控件:
隐藏控件后需调用layout.update()
或adjustSize()
更新布局。
六、与其他布局对比
QGridLayout | QVBoxLayout/QHBoxLayout | QFormLayout |
---|---|---|
适合多行多列复杂布局 | 适合简单线性布局 | 适合标签-输入框成对排列 |
灵活控制行列比例和跨度 | 仅支持单行或单列排列 | 自动处理标签和输入框对齐 |
通过 QGridLayout
,可以轻松实现精确的网格布局,结合跨行列和拉伸因子,完美适配复杂的界面设计需求!