基本布局示例
演示如何使用标准布局管理器。
“基本布局”演示了如何使用 Qt 中提供的标准布局管理器:QBoxLayout 、QGridLayout 和QFormLayout 。

QBoxLayout 类可将小部件水平或垂直排列。QHBoxLayout 和QVBoxLayout 是QBoxLayout 的便捷子类。QGridLayout 通过将可用空间划分为行和列,将小部件布局在单元格中。而QFormLayout 则将其子元素以两列形式排列,左列放置标签,右列放置输入字段。
如需了解更多信息,请访问“布局管理”页面。
运行示例
您可以通过以下方式运行示例:
- Qt Creator
打开“Welcome ”模式,并从“Examples ”中选择该示例。有关更多信息,请参阅Qt Creator :教程:构建和运行。
- Qt Extension for Visual Studio Code
在Command Palette 中运行Qt: Open Qt examples 命令,并从列表中选择该示例。有关更多信息,请参阅Qt Extension for Visual Studio Code :教程:构建与运行。
对话框类定义
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog();
private:
void createMenu();
void createHorizontalGroupBox();
void createGridGroupBox();
void createFormGroupBox();
enum { NumGridRows = 3, NumButtons = 4 };
QMenuBar *menuBar;
QGroupBox *horizontalGroupBox;
QGroupBox *gridGroupBox;
QGroupBox *formGroupBox;
QTextEdit *smallEditor;
QTextEdit *bigEditor;
QLabel *labels[NumGridRows];
QLineEdit *lineEdits[NumGridRows];
QPushButton *buttons[NumButtons];
QDialogButtonBox *buttonBox;
QMenu *fileMenu;
QAction *exitAction;
};Dialog 类继承自QDialog 。这是一个自定义控件,它使用以下几何管理器来显示其子控件:QHBoxLayout 、QVBoxLayout 、QGridLayout 以及QFormLayout 。
该类包含四个私有函数,用于简化类构造函数:createMenu() 、createHorizontalGroupBox() 、createGridGroupBox() 和createFormGroupBox() 这四个函数会创建若干小部件,示例通过这些小部件演示布局如何影响其外观。
对话框类的实现
Dialog::Dialog()
{
createMenu();
createHorizontalGroupBox();
createGridGroupBox();
createFormGroupBox();在构造函数中,我们首先使用createMenu() 函数创建并填充一个菜单栏,并使用createHorizontalGroupBox() 函数创建一个包含四个按钮且采用水平布局的组框。 接下来,我们使用createGridGroupBox() 函数创建一个组框,其中包含多个行编辑框和一个小型文本编辑器,这些控件以网格布局显示。最后,我们使用createFormGroupBox() 函数创建一个组框,其中包含三个标签和三个输入字段:一个行编辑框、一个下拉列表框和一个旋转框。
bigEditor = new QTextEdit;
bigEditor->setPlainText(tr("This widget takes up all the remaining space "
"in the top-level layout."));
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);我们还创建了一个大型文本编辑器和一个对话框按钮框。QDialogButtonBox 类是一个小部件,它会根据当前小部件样式,以合适的布局呈现按钮。可以通过在构造函数中使用QDialogButtonBox::StandardButtons 枚举来指定首选的按钮类型。
请注意,在创建控件时无需指定父控件。原因是此处创建的所有控件都将被添加到布局中,而当控件被添加到布局时,其父控件会自动更改为该布局所安装的控件。
QVBoxLayout *mainLayout = new QVBoxLayout;主布局是一个QVBoxLayout 对象。QVBoxLayout 是一个用于垂直方向盒式布局的便捷类。
通常情况下,QBoxLayout 类会将其获得的空间(来自父布局或父控件)划分为一系列区域,并让每个受管理的控件填满其中一个区域。如果QBoxLayout 的布局方向为Qt::Horizontal ,则这些区域将按行排列;如果布局方向为Qt::Vertical ,则这些区域将按列排列。 相应的便捷类分别是QHBoxLayout 和QVBoxLayout 。
mainLayout->setMenuBar(menuBar);当我们调用QLayout::setMenuBar()函数时,布局会将提供的菜单栏放置在父控件的顶部,且位于该控件的content margins 之外。所有子控件均被放置在菜单栏下边缘的下方。
mainLayout->addWidget(horizontalGroupBox);
mainLayout->addWidget(gridGroupBox);
mainLayout->addWidget(formGroupBox);
mainLayout->addWidget(bigEditor);
mainLayout->addWidget(buttonBox);我们使用QBoxLayout::addWidget()函数将小部件添加到布局的末尾。每个小部件将至少获得其最小尺寸,至多获得其最大尺寸。可以在addWidget()函数中指定伸缩因子,多余的空间将根据这些伸缩因子进行分配。若未指定,小部件的伸缩因子默认为0。
setLayout(scrollLayout);
setWindowTitle(tr("Basic Layouts"));
}我们使用QWidget::setLayout() 函数将主布局安装到Dialog 小部件上,布局中的所有小部件都会自动重新归属,成为Dialog 小部件的子项。
void Dialog::createMenu()
{
menuBar = new QMenuBar;
fileMenu = new QMenu(tr("&File"), this);
exitAction = fileMenu->addAction(tr("E&xit"));
menuBar->addMenu(fileMenu);
connect(exitAction, &QAction::triggered, this, &QDialog::accept);
}在私有函数createMenu() 中,我们创建了一个菜单栏,并添加了一个下拉菜单File ,其中包含一个Exit 选项。
void Dialog::createHorizontalGroupBox()
{
horizontalGroupBox = new QGroupBox(tr("Horizontal layout"));
QHBoxLayout *layout = new QHBoxLayout;
for (int i = 0; i < NumButtons; ++i) {
buttons[i] = new QPushButton(tr("Button %1").arg(i + 1));
layout->addWidget(buttons[i]);
}
horizontalGroupBox->setLayout(layout);
}创建水平组框时,我们使用QHBoxLayout 作为内部布局。我们创建要放入组框中的按钮,将其添加到布局中,并将其安装到组框上。
void Dialog::createGridGroupBox()
{
gridGroupBox = new QGroupBox(tr("Grid layout"));在createGridGroupBox() 函数中,我们使用QGridLayout 来以网格形式布局控件。它会利用可用的空间(由其父布局或父控件提供),将其划分为行和列,并将管理的每个控件放置到正确的单元格中。
for (int i = 0; i < NumGridRows; ++i) {
labels[i] = new QLabel(tr("Line %1:").arg(i + 1));
lineEdits[i] = new QLineEdit;
layout->addWidget(labels[i], i + 1, 0);
layout->addWidget(lineEdits[i], i + 1, 1);
}对于网格中的每一行,我们创建一个标签和一个关联的行编辑框,并将它们添加到布局中。QGridLayout::addWidget() 函数与QBoxLayout 中的对应函数有所不同:它需要行和列参数来指定要放置控件的网格单元格。
smallEditor = new QTextEdit;
smallEditor->setPlainText(tr("This widget takes up about two thirds of the "
"grid layout."));
layout->addWidget(smallEditor, 0, 2, 4, 1);QGridLayout::addWidget() 还可以接受参数,指定该控件将横跨的行数和列数。在此示例中,我们创建了一个横跨三行一列的小型编辑器。
对于QBoxLayout::addWidget() 和QGridLayout::addWidget() 这两个函数,还可以添加最后一个参数来指定小部件的对齐方式。默认情况下,小部件会填满整个单元格。但我们可以,例如,通过将对齐方式指定为Qt::AlignRight 来将小部件对齐到右侧边缘。
layout->setColumnStretch(1, 10);
layout->setColumnStretch(2, 20);
gridGroupBox->setLayout(layout);
}网格布局中的每一列都有一个拉伸因子。该拉伸因子通过QGridLayout::setColumnStretch() 进行设置,并决定该列在满足其必要最小空间需求之外,还能获得多少可用空间。
在此示例中,我们为第 1 列和第 2 列设置了拉伸因子。拉伸因子是相对于网格中其他列而言的;拉伸因子较高的列将占据更多的可用空间。 因此,在我们的网格布局中,第 2 列将比第 1 列占用更多的可用空间,而第 0 列由于其拉伸因子为 0(默认值),因此不会扩展。
列和行的行为完全相同;行也有相应的拉伸因子,以及QGridLayout::setRowStretch()函数。
void Dialog::createFormGroupBox()
{
formGroupBox = new QGroupBox(tr("Form layout"));
QFormLayout *layout = new QFormLayout;
layout->addRow(new QLabel(tr("Line 1:")), new QLineEdit);
layout->addRow(new QLabel(tr("Line 2, long text:")), new QComboBox);
layout->addRow(new QLabel(tr("Line 3:")), new QSpinBox);
formGroupBox->setLayout(layout);
}在createFormGroupBox() 函数中,我们使用QFormLayout 将对象整齐地排列为两列——名称列和字段列。共有三个QLabel 对象用于存储名称,并配有三个对应的输入控件作为字段:QLineEdit 、QComboBox 和QSpinBox 。与QBoxLayout::addWidget()和QGridLayout::addWidget()不同,我们使用QFormLayout::addRow()将控件添加到布局中。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.