表单布局 QFormLayout
以两列形式布局其子项。左列由标签组成,右列由小部件(行编辑器、数字调整框等)组成。
如下图,有两列布局,左侧为标签,右侧为行编辑框或下拉列表,就可以用QFormLayout
实现。
一、创建QFormLayout
和 QGridLayout
一样,QFormLayout
也只有一个构造函数:
explicit QFormLayout(QWidget *parent = nullptr);
可以通过拖动控件创建,也可以使用代码直接创建。
由于布局是默认铺满父级Widget
的,为了方便控制布局的整体大小,一般不是将最外层的Widget
窗口传给QFormLayout
,而是再新建一个Widget
,如下:
// 创建指针
QWidget *formLayoutWidget;
QFormLayout *formLayout;
// 创建新Widget
formLayoutWidget = new QWidget(Widget);
// 为新Widget设置大小
formLayoutWidget->setGeometry(QRect(60, 60, 531, 291));
// 实例化布局对象,并将新Widget传入
formLayout = new QFormLayout(formLayoutWidget);
二、成员函数
2.1. 对行操作
对于表单布局,可以以行为单位作为一个成员,并对其进行操作。
a. 添加行:
void addRow(QWidget *label, QWidget *field); // 使用指定的标签和小部件在表单末尾添加一行
void addRow(QWidget *label, QLayout *field);
void addRow(const QString &labelText, QWidget *field);
void addRow(const QString &labelText, QLayout *field);
void addRow(QWidget *widget); // 直接在表单末尾添加小部件,此时小部件占两列
void addRow(QLayout *layout);
b. 插入行:
参数同addRow
,不同的是可以通过row
指定新行的位置。
void insertRow(int row, QWidget *label, QWidget *field);
void insertRow(int row, QWidget *label, QLayout *field);
void insertRow(int row, const QString &labelText, QWidget *field);
void insertRow(int row, const QString &labelText, QLayout *field);
void insertRow(int row, QWidget *widget);
void insertRow(int row, QLayout *layout);
c. 删除行:
删除行的同时删除该行所有小部件及嵌套布局,所有后续行都向上移动一行。
void removeRow(int row); // 指定行索引
void removeRow(QWidget *widget); // 指定行小部件对象
void removeRow(QLayout *layout); // 指定行布局对象
只从布局中删除行,不删除小部件,其余同removeRow
TakeRowResult takeRow(int row);
TakeRowResult takeRow(QWidget *widget);
TakeRowResult takeRow(QLayout *layout);
2.2. 操作布局项
当然也可以操作每一个子项,如下:
a. 将给定行的布局项设置为item
、widget
、layout
void setItem(int row, ItemRole role, QLayoutItem *item);
void setWidget(int row, ItemRole role, QWidget *widget);
void setLayout(int row, ItemRole role, QLayout *layout);
请勿使用setItem()
添加子布局或子小部件项目,请使用 setLayout()
或 setWidget()
。
其中布局项通过role
指定,ItemRole
是一个枚举:
enum ItemRole {
LabelRole = 0,
FieldRole = 1,
SpanningRole = 2
};
描述如下:
常量 | 值 | 描述 |
---|---|---|
QFormLayout::LabelRole | 0 | 左列的标签项 |
QFormLayout::FieldRole | 1 | 右列的小部件 |
QFormLayout::SpanningRole | 2 | 横跨左右两列 |
示例如下:
b. 获取item
、widget
、layout
的位置
void getItemPosition(int index, int *rowPtr, ItemRole *rolePtr) const;
void getWidgetPosition(QWidget *widget, int *rowPtr, ItemRole *rolePtr) const;
void getLayoutPosition(QLayout *layout, int *rowPtr, ItemRole *rolePtr) const;
通过给定的index
、widget
、layout
获取项所在的行(*rowPtr)和列(*rolePtr),如果给定的项不存在,则*rowPtr
为-1
,*rolePtr
保持原来的值不变,其中index
是布局项在队列中的索引(从0开始)。
c. 获取右列小部件对应的label对象
QWidget *labelForField(QWidget *field) const;
QWidget *labelForField(QLayout *field) const;
d. 通过索引与位置访问布局项
QLayoutItem *itemAt(int row, ItemRole role) const;
// reimplemented from QLayout
QLayoutItem *itemAt(int index) const override;
e. 添加/删除布局项
// reimplemented from QLayout
void addItem(QLayoutItem *item) override;
QLayoutItem *takeAt(int index) override;
2.3. 间距
void setHorizontalSpacing(int spacing); // 设置水平间距
int horizontalSpacing() const; // 获取水平间距
void setVerticalSpacing(int spacing); // 设置垂直间距
int verticalSpacing() const; // 获取垂直间距
void setSpacing(int) override; // 同时设置水平和垂直间距
int spacing() const override; // 同时获取水平和垂直间距(若水平和垂直间距不相等,则返回-1)
2.4. 设置布局规则
void setFieldGrowthPolicy(FieldGrowthPolicy policy);
FieldGrowthPolicy fieldGrowthPolicy() const;
void setRowWrapPolicy(RowWrapPolicy policy);
RowWrapPolicy rowWrapPolicy() const;
其中FieldGrowthPolicy
定义右列小部件的布局规则,枚举如下:
enum FieldGrowthPolicy {
FieldsStayAtSizeHint,
ExpandingFieldsGrow,
AllNonFixedFieldsGrow
};
描述如下:
常量 | 值 | 描述 |
---|---|---|
QFormLayout::FieldsStayAtSizeHint | 0 | 大小永远不会超出其有效大小提示(QWidgetItem::sizeHint()) |
QFormLayout::ExpandingFieldsGrow | 1 | 小部件的水平大小策略为 Expanding 或 MinimumExpanding 时,其被拉伸以填充可用空间。其他小部件不会超出其有效大小提示。 |
QFormLayout::AllNonFixedFieldsGrow | 2 | 只要小部件的大小策略允许拉伸,都将被拉伸以填充可用空间。 这是大多数样式的默认策略。 |
RowWrapPolicy
定义换行策略,枚举如下:
enum RowWrapPolicy {
DontWrapRows,
WrapLongRows,
WrapAllRows
};
描述如下:
常量 | 值 | 描述 |
---|---|---|
QFormLayout::DontWrapRows | 0 | 右列小部件总是排列在对应的标签旁边 |
QFormLayout::WrapLongRows | 1 | 空间优先分配给标签,其余的空间被分配给右列小部件。 如果最小的小部件的大小大于可用空间,则该小部件将换行到下一行。 |
QFormLayout::WrapAllRows | 2 | 右列小部件总是排列在对应的标签下方 |
2.5. 对齐方式
void setLabelAlignment(Qt::Alignment alignment); // 设置标签列的水平对齐方式
Qt::Alignment labelAlignment() const;
void setFormAlignment(Qt::Alignment alignment); // 设置布局的对齐方式
Qt::Alignment formAlignment() const;