基本布局示例
演示如何使用标准布局管理器。
基本布局 展示如何在 Qt 中使用标准布局管理器,包括:QBoxLayout、QGridLayout 和 QFormLayout。
QBoxLayout 类水平或垂直排列小部件。 QHBoxLayout 和 QVBoxLayout 是 QBoxLayout 的便捷子类。 QGridLayout 将小部件布局在单元格中,通过将可用空间分成行和列来布局。另一方面,QFormLayout 在两列表单中设置其子项,左侧为标签,右侧为输入字段。
有关更多信息,请访问布局管理页面。
运行示例
要从 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,则盒子将放置在一列中。对应的便利类分别是 QHBoxLayout 和 QVBoxLayout。
mainLayout->setMenuBar(menuBar);
当我们调用 QLayout::setMenuBar() 函数时,布局会将提供的菜单栏放置在父小部件的顶部,并在小部件的 内容边距 之外。所有子小部件都放置在菜单栏的底部边缘以下。
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()
中,我们创建一个菜单栏,并添加一个包含 退出 选项的下拉 文件 菜单。
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); }
对于网格中的每一行,我们都创建一个标签和一个相关的行编辑,并将它们添加到布局中。与 QBoxLayout 中的对应函数不同的是,QGridLayout::addWidget() 需要指定要放置小部件的网格单元格的行和列。
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() 将小部件添加到布局中。
© 2024 The Qt Company Ltd。本文件中包含的文档贡献是各自所有者的版权。本文件中的文档是根据自由软件基金会发布的 GNU 自由文档许可证版本 1.3 的条款许可的。Qt 及其相关标志是芬兰和/或世界其他地区的 The Qt Company Ltd 的商标。所有其他商标均为各自所有者的财产。