基本布局示例

演示如何使用标准布局管理器。

基本布局示例展示了如何使用 Qt 中的标准布局管理器:QBoxLayoutQGridLayoutQFormLayout

基本布局示例截图

QBoxLayout 类可水平或垂直排列部件。QHBoxLayoutQVBoxLayoutQBoxLayout 的便利子类。QGridLayout 通过将可用空间划分为行和列,将部件排列在单元格中。QFormLayout另一方面,"...... "将其子控件设置为双栏形式,标签位于左栏,输入框位于右栏。

更多信息,请访问布局管理页面。

运行示例

运行示例 Qt Creator,打开Welcome 模式,然后从Examples 中选择示例。更多信息,请参阅Qt Creator: 教程:构建并运行

对话框类定义

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 ,则将方框放置在一列中。相应的方便类分别是QHBoxLayoutQVBoxLayout

    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 widget 上安装主布局,而布局中的所有 widget 都会自动重新成为Dialog widget 的子 widget。

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() 函数中,我们创建了一个菜单栏,并添加了一个包含Exit 选项的下拉File 菜单。

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 对象,字段有三个相应的输入部件:QLineEditQComboBoxQSpinBox 。与QBoxLayout::addWidget() 和QGridLayout::addWidget() 不同,我们使用QFormLayout::addRow() 将部件添加到布局中。

示例项目 @ code.qt.io

© 2025 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.