控件表单布局QFormLayout
表单布局QFormLayout 由左右两列和多行构成将控件放到左右两列中,通常左列放置QLabel 控件,右列放置 QLineEdit 控件QSpinBox 等输人控件,也可以让一个控件单独占据一行。表单布局支持嵌套。
表单布局QFormLayout 继承自QLayout,用QFormLayout类创建实例对象的方法如下所示,其中 parent 是窗口或容器类控件。
from PySide6.QtWidgets import QFormLayout
QFormLayout(parent: Union[PySide6.QtWidgets.QWidget,NoneType]= None)-> None
表单布局QFormLayout官方描述
QFormLayout是一个方便的布局类,它以两列的形式排列其子级。左列由标签组成,右列由"字段"小部件行编辑器、旋转框等组成。
传统上,这样的两列形式布局是使用QGridLayout实现的。QFormLayout是一种更高级别的替代方案,具有以下优势:
-
遵守不同平台的外观准则。
例如,macOS Aqua和KDE指南规定标签应该右对齐,而Windows和GNOME应用程序通常使用左对齐。 -
支持包裹长排。
对于具有小型显示器的设备,可以将QFormLayout设置为换行长行,甚至换行所有行。 -
创建标签-字段对的便捷API。
addRow重载使用一个QString和一个QWidget*在后台创建一个QLabel并自动设置其好友。然后我们可以编写这样的代码:formLayout = QFormLayout(self) formLayout.addRow(tr("Name:"), nameLineEdit) formLayout.addRow(tr("Email:"), emailLineEdit) formLayout.addRow(tr("Age:"), ageSpinBox)
将其与以下使用QGridLayout编写的代码进行比较:
gridLayout = QGridLayout(self) nameLabel = QLabel(tr("Name:")) nameLabel.setBuddy(nameLineEdit) emailLabel = QLabel(tr("Name:")) emailLabel.setBuddy(emailLineEdit) ageLabel = QLabel(tr("Name:")) ageLabel.setBuddy(ageSpinBox) gridLayout.addWidget(nameLabel, 0, 0) gridLayout.addWidget(nameLineEdit, 0, 1) gridLayout.addWidget(emailLabel, 1, 0) gridLayout.addWidget(emailLineEdit, 1, 1) gridLayout.addWidget(ageLabel, 2, 0) gridLayout.addWidget(ageSpinBox, 2, 1)
下表显示了不同样式的默认外观。
QCommonStyle
派生样式QPlastiqueStyle除外QMacStyle QPlastiqueStyle Qt Extended styles 用于Windows、GNOME和早期版本的KDE的传统样式。标签是左对齐的,扩展字段会增长以填充可用空间。这通常对应于我们使用两列QGridLayout所得到的结果。 基于macOS Aqua指南的风格。标签是右对齐的,字段不会超出其大小提示,并且表单是水平居中的。 KDE应用程序的推荐样式。与MacStyle类似,只是表单是左对齐的,并且所有字段都会增长以填充可用空间。 Qt扩展样式的默认样式。标签右对齐,扩展字段增加以填充可用空间,并为长行启用行换行。 也可以通过调用setLabelAlignment、setFormAlign、setFieldGrowthPolicy和setRowWrapPolicy分别重写表单样式。例如,要模拟QMacStyle在所有平台上的表单布局外观,但使用左对齐的标签,可以编写:
formLayout.setRowWrapPolicy(QFormLayout.DontWrapRows) formLayout.setFieldGrowthPolicy(QFormLayout.FieldsStayAtSizeHint) formLayout.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop) formLayout.setLabelAlignment(Qt.AlignLeft)
表单布局QFormLayout属性
属性 | 描述 | 方法 |
---|---|---|
fieldGrowthPolicy: FieldGrowthPolicy | 此属性保持表单字段的增长方式。 默认值取决于小部件或应用程序样式。对于QMacStyle,默认值为FieldsStayAtSizeHint;对于QCommonStyle派生的样式如Plastique和Windows,默认为ExpandingFieldsGrow;对于Qt扩展样式,默认值为AllNonFixedFieldsGrow。 如果没有任何字段可以增长,并且调整了表单的大小,则会根据当前表单对齐方式分配额外的空间。 | fieldGrowthPolicy () setFieldGrowthPolicy (policy) |
formAlignment: Alignment | 此属性保留表单布局的内容在布局的几何图形中的对齐方式。 默认值取决于小部件或应用程序样式。对于QMacStyle,默认值为`AlignHCenter | AlignTop` |
horizontalSpacing: int | 此属性保留并排排列的小部件之间的间距。 默认情况下,如果没有显式设置值,则布局的水平间距将从父布局或父小部件的样式设置继承。 | horizontalSpacing () setHorizontalSpacing (spacing) |
labelAlignment: Alignment | 此属性保留标签的水平对齐方式。 默认值取决于小部件或应用程序样式。对于QCommonStyle派生的样式,除QPlastiqueStyle外,默认为AlignLeft;对于其他样式,默认为AlignRight。 | labelAlignment () setLabelAlignment (alignment) |
rowWrapPolicy: RowWrapPolicy | 此属性保留窗体的行换行方式。 默认值取决于小部件或应用程序样式。对于Qt扩展样式,默认为WrapLongRows;对于其他样式,默认为DontWrapRows。 如果要将每个标签显示在其关联字段的上方而不是旁边,请将此属性设置为WrapAllRows。 | rowWrapPolicy () setRowWrapPolicy (policy) |
verticalSpacing: int | 此属性保留垂直排列的小部件之间的间距。 默认情况下,如果没有显式设置值,则布局的垂直间距将从父布局或父小部件的样式设置继承。 | verticalSpacing () setVerticalSpacing (spacing) |
表单布局QFormLayout 的常用方法
表单布局QFormLayout 的常用方法如表所示,主要方法介绍如下。
-
用addRow()方法在底部添加行,用insertRow()方法在中间插人行。addRow()和insertRow()方法是重构型方法,有多种不同的参数。
- 用addRow(label.QWidget,field;QWidget)和addRow(label:QWidget;field;QLayout)方法在左列放置第1个QWidget,在右列放置第2个QWidget或 QLayout;
- 用addRow(labelText:str,field:QWidget)addRow(labelText:str,field;QLayout)方法在左列创建标题是 str的 QLabel 控件,在右列放置QWidget或QLayout,这时新建的 QLabel和QWidget 或 QLayouthis 已经是伙伴关系;
- 用addRow(widget:QWidget)和 addRow(layout;QLayout)方法把控件和布局放置到一行上,占据左右两列的位置。
-
水平和竖直方向的间距
- 用setHorizontalSpacing(spacing:int)setVerticalSpacing(spacing:int)方法可以分别设置控件在水平和竖直方向的间距。
-
对齐方式
-
用setLabelAlignment(Qt.Alignment)方法可以设置左列控件的文字对齐方式
-
用setFormAlignment(alignment: PySide6.QtCore.Qt.AlignmentFlag)方法可以设置表单布局内控件的水平和竖直方向的对齐方式,其中参数Qt.Qlignment 可以取:
PySide6.QtCore.Qt.AlignmentFlag继承enum.IntFlag 此枚举类型用于描述对齐。它包含水平和垂直标志,这些标志可以组合在一起以产生所需的效果。TextElideMode枚举也可以在许多情况下用于微调对齐文本的外观。
-
水平标志为:
Constant Description Qt.AlignLeft 与左边缘对齐。 Qt.AlignRight 与右边缘对齐。 Qt.AlignHCenter 在可用空间中水平居中。 Qt.AlignJustify 在可用空间中对正文本。 -
垂直标志为:
Constant Description Qt.AlignTop 与顶部对齐。 Qt.AlignBottom 与底部对齐。 Qt.AlignVCenter 在可用空间中垂直居中。 Qt.AlignBaseline 与基线对齐。 -
一次只能使用其中一个水平标志。有一个二维标志:
Constant Description Qt.AlignCenter 在两个维度上居中。水平和竖直都在中心。
一次最多可以使用一个水平和一个垂直标志。Qt::AlignCenter同时计算为水平和垂直。
三个枚举值在可以以从右到左模式运行的应用程序中很有用:Constant Description Qt.AlignAbsolute 如果小部件的布局方向是RightToLeft而不是默认的LeftToRight,Qt::AlignLeft指的是右边缘,Qt:::AlignRight指的是左边缘。这通常是所需的行为。如果您希望Qt::AlignLeft始终表示"左",Qt:;AlignRight始终表示"右",请将标志与Qt:∶AlignAbsolute组合。 Qt.AlignLeading Qt::AlignLeft的同义词。 Qt.AlignTrailing Qt::AlignRight的同义词。 -
-
-
左列控件和右列控件的换行策略
-
用setRowWrapPolicy(QFormLayout.RowWrapPolicy)方法可以设置左列控件和右列控件的换行策略,参数QFormLayoutRowWrapPolicy :
PySide6.QtWidgets.QFormLayout.RowWrapPolicy 此枚举指定可用于控制表单行换行方式的不同策略。
Constant Description QFormLayout.DontWrapRows 字段总是排列在其标签旁边。这是除Qt扩展样式外的所有样式的默认策略。 QFormLayout.WrapLongRows 标签有足够的水平空间来容纳最宽的标签,其余空间则分配给字段。如果字段对的最小大小比可用空间宽,则将该字段换行到下一行。这是Qt扩展样式的默认策略。 QFormLayout.WrapAllRows 字段总是排列在其标签下方。
-
-
设置可伸缩控件的伸缩方式
-
用setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy)方法可以设置可伸缩控件的伸缩方式,右列的输人控件通常可以随着窗体的改变而改变,宽度是可调节的。参数QFormLayout.FieldGrowthPolicy:
PySide6.QtWidgets.QFormLayout.FieldGrowthPolicy 此枚举指定可用于控制表单字段增长方式的不同策略。
Constant Description QFormLayout.FieldsStayAtSizeHint 表示控件的伸缩量不会超过有效的范围,控件尺寸由sizeHint()方法获取的值设置; QFormLayout.ExpandingFieldsGrow 水平大小策略为Expanding或MinimumExpanding的字段将增长以填充可用空间。其他字段的增长不会超过其有效大小提示。这是Plastique的默认策略。
对于设置了水平setSizePolicy()属性或最小伸缩量的控件使其扩充到可以使用的空间,其他没有设置setSizePolicy()属性的控件在有效的范围内变化;QFormLayout.AllNonFixedFieldsGrow 所有具有允许其增长的大小策略的字段都将增长以填充可用空间。这是大多数样式的默认策略。
对于设置了 setSizePolicy()属性的控件,使其扩充到可以使用的空间 -
设置控件随窗口大小改变时尺寸的变化方式
用setSizeConstraint(arg__1: PySide6.QtWidgets.QLayout.SizeConstraint)方法可以设置控件随窗口大小改变时尺寸的变化方式,这是从 QLayout 继承过来的方法。枚举类型参数 QLayout.SizeConstraint:
Constant Description QLayout.SetDefaultConstraint 主小部件的最小大小设置为minimumSize,除非小部件已经有了最小大小。
控件的最小尺寸根据setMinimunSize(QSize)方法或setMinimunSize(int,int)方法设定的值确定;QLayout.SetFixedSize 主窗口小部件的大小设置为sizeHint;它根本无法调整大小。 QLayout.SetMinimumSize 主窗口小部件的最小大小设置为minimumSize;它不能再小了。 QLayout.SetMaximumSize 主窗口小部件的最大大小设置为maximumSize;它不能再大了。 QLayout.SetMinAndMaxSize 主窗口小部件的最小大小设置为minimumSize,最大大小设置为maximumSize。 QLayout.SetNoConstraint 小部件不受约束。
QFormLayout的方法及参数类型 说 .明 addRow(label: QWidget,field:QWidget) 末尾添加行,两个控件分别在左右 addRow(label:QWidget,field: QLayout) 末尾添加行,控件在左,布局在右 addRow(labelText: str,field:QWidget) 末尾添加行,左侧创建名称为str的标签,右侧是控件 addRow(labelText: str,field:QLayout) 末尾添加行,左侧创建名称为str的标签,右侧是布局 addRow(widget: QWidget) 末尾添加行,只有1个控件,控件占据左右两列 addRow(layout: QLayout) 末尾添加行,只有:1个布局,布局占据左右两列 insertRow(row:int,QWidget,QWidget) 在第row行插人,两个控件分别在左右 insertRow(row:int,QWidget,QLayout) 在第row行插人,控件在左,布局在右 insertRow(row:int,str,QWidget) 在第row行插人,左侧创建名称为 str的标签,右侧是控件 insertRow(row:int,str,QLayout) 在第row行插人,左侧创建名称为str的标签,右侧是布局 insertRow(row:int,QWidget) 在第row行插入,只有1个控件,控件占据左右两列 insertRow(row:int,QLayout) 在第row行插入,只有1个布局,布局占据左右两列 removeRow(row:int) 删除第row行及其控件 . removeRow(layout:QLayout) 删除布局 removeRow(widget:QWidget) 删除控件 setHorizontalSpacing(spacing:int) 设置水平方向的间距 setVerticalSpacing(spacing: int) 设置竖直方向的间距 setRowWrapPolicy(QFormLayout RowWrapPolicy) 设置左列控件和右列控件的换行策略 rowCount() 返回表单布局中行的数量 setLabelAlignment(Qt.Alignment) 设置左列的对齐方法 setFormAlignment(Qt.Alignment) 设置控件在表单布局中的对齐方法 setContentsMargins(int,int,int,int)setContentsMargins(QMargins) 设置布局内的控件与布局外边界的左、上、右、下的距离 setFieldGrowthPolicy(QFormLayout FieldGrowthPolicy) 设置可伸缩控件的伸缩方式 setSizcConstraint(QLayout.SizeConstraint) 设置控件随窗口大小改变时尺寸的变化方式 -
表单布局QFormLayout 的应用实例
下面的程序在窗口中用表单布局建立一些控件的布局,用于输人一些基本信息,程序运行界面如图所示。
from PySide6.QtWidgets import(QApplication,QWidget,QLineEdit,QSpinBox,QLabel,QTextBrowser,QFormLayout,QRadioButton,QHBoxLayout,QPushButton)
from PySide6.QtCore import Qt
import sys
class myWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QFormLayout")
self.resize(300,200)
self.setupUi()
def setupUi(self):
formLayout = QFormLayout(self)
name = QLabel("姓名(&N):")
self.name_lineEdit = QLineEdit()
name.setBuddy(self.name_lineEdit)
formLayout.addRow(name,self.name_lineEdit)# 添加行
number = QLabel("学号(&B):")
self.number_lineEdit = QLineEdit()
number.setBuddy(self.number_lineEdit)# 定义伙伴关系
formLayout.addRow(number,self.number_lineEdit)# 添加行
self.age_spinBox = QSpinBox()
formLayout.addRow("年龄(&A);",self.age_spinBox)# 添加行
self.male_radioButton = QRadioButton("男(&M)")
self.male_radioButton.setChecked(True)
self.female_radioButton = QRadioButton("女(&F)")
h_layout = QHBoxLayout()
h_layout.addWidget(self.male_radioButton)
h_layout.addWidget(self.female_radioButton)
formLayout.addRow("性别:",h_layout)# 添加行
self.append_btn = QPushButton("添加(&A)")
formLayout.addRow(self.append_btn)# 添加行
self.address_lineEdit = QLineEdit()
formLayout.insertRow(4,"地址(&D);",self.address_lineEdit)# 插人行
self.class_lineEdit = QLineEdit()
formLayout.insertRow(4,"班级(&C):",self.class_lineEdit)# 插人行
self.textBrowser = QTextBrowser()
formLayout.addRow(self.textBrowser)# 添加行,按钮单独占据一行
formLayout.setLabelAlignment(Qt.AlignRight)# 对齐方式
self.append_btn.clicked.connect(self.append_clicked)# 信号与槽函数的连接
def append_clicked(self):
sex ="男"
if self.female_radioButton.isChecked():
sex ="女"
template ="姓名:{} 学号:{} 年龄:{} 性别:{} 班级:{} 地址:{}"
self.textBrowser.append(template.format(self.name_lineEdit.text(),
self.number_lineEdit.text(),
self.age_spinBox.value(),
sex,
self.class_lineEdit.text(),
self.address_lineEdit.text()))
if __name__ =='__main__':
app = QApplication(sys.argv)
win = myWindow()
win.show()
sys.exit(app.exec())