Basic Layouts Example
演示如何使用标准布局管理器。
基本布局显示如何使用Qt中提供的标准布局管理器:QBoxLayout、QGridLayout和QFormLayout。
QBoxLayout类水平或垂直排列小部件。QHBoxLayout和QVBoxLayout是QBoxLayout的便利子类。QGridLayout通过将可用空间划分为行和列来在单元格中布局小部件。另一方面,QFormLayout将其子级设置为两列形式,标签位于左列,输入字段位于右列。
有关详细信息,请访问布局管理页面。
Dialog Class 定义
Dialog类继承QDialog。它是一个自定义小部件,使用几何体管理器显示其子小部件:QHBoxLayout、QVBoxLayout、QGridLayout和QFormLayout。
有四个私有函数可以简化类构造函数:createMenu() 、createHorizontalGroupBox() 、createGridGroupBox() 和createFormGroupBox() 函数创建几个小部件,示例使用这些小部件演示布局如何影响它们的外观。
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 Class 实现
#include <QtWidgets>
#include "Dialog.h"
Dialog::Dialog()
{
createMenu(); // 创建并填充菜单栏
createHorizontalGroupBox(); // 创建一个包含四个水平布局按钮的组框
createGridGroupBox(); // 创建一个组框,其中包含多个行编辑和一个小的文本编辑器
createFormGroupBox(); // 创建包含3个标签和3个输入字段的组框:一个行编辑、一个组合框和一个数字调整框。
/*创建一个大的文本编辑器和一个对话框按钮。
* 注意,我们在创建小部件时不必为其指定父级。 原因是我们在此处创建的所有窗口小部件都将添加到布局中,
并且当我们将窗口小部件添加到布局中时,它会自动重新绑定到安装该布局的窗口小部件。 */
bigEditor = new QTextEdit; // 创建一个大的文本编辑器
bigEditor->setPlainText(tr("This widget takes up all the remaining space "
"in the top-level layout."));
/*QDialogButtonBox类是一个小部件,它以适合当前小部件样式的布局显示按钮。
使用QDialogButtonBox::StandardButtons枚举将首选按钮指定为构造函数的参数。*/
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
/*主布局是QVBoxLayout对象
* 一般来说,QBoxLayout类接受(从其父布局或父小部件)获得的空间,将其划分为一系列框,
并使每个托管小部件填充一个框。
* 如果QBoxLayout的方向是Qt::Horizontal,则框将放置在一行中。
如果方向为Qt::Vertical,则将框放置在一列中。
相应的便利类分别是QHBoxLayout和QVBoxLayout。*/
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->setMenuBar(menuBar); // 布局将提供的菜单栏放在父部件的顶部,所有子部件都放置在菜单栏的底部边缘下面
mainLayout->addWidget(horizontalGroupBox);
mainLayout->addWidget(gridGroupBox);
mainLayout->addWidget(formGroupBox);
mainLayout->addWidget(bigEditor);
mainLayout->addWidget(buttonBox); // 小部件添加到布局的末尾。小部件将至少获得它的最小大小,最多获得它的最大大小
/*可以在addWidget()函数中指定拉伸因子,并且拉伸因子共享任何多余的空间。如果未指定,小部件的拉伸因子为 0*/
setLayout(mainLayout); // 使用QWidget::setLayout()函数在对话框小部件上安装主布局
setWindowTitle(tr("Basic Layouts"));
}
/*创建了一个菜单栏,并添加了一个包含退出选项的下拉文件菜单。*/
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);
}
/*创建水平分组框时,使用QHBoxLayout作为内部布局。*/
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);
}
/* createGridGroupBox()函数中,使用了QGridLayout,在网格中布局小部件。
* 利用可用的空间(通过其父布局或其父小部件),将其划分为行和列,并将它管理的每个小部件放入正确的单元格中。*/
void Dialog::createGridGroupBox()
{
gridGroupBox = new QGroupBox(tr("Grid layout"));
QGridLayout *layout = new QGridLayout;
/* 对于网格中的每一行,我们创建一个标签和一个相关的行编辑,并将它们添加到布局中。
* QGridLayout::addWidget()函数需要指定放置小部件的网格单元格的行和列。
* QGridLayout::addWidget()还可以指定单元格将跨越的行数和列数。*/
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);
}
smallEditor = new QTextEdit;
smallEditor->setPlainText("This widget takes up about two thirds of the grid layout.");
// 使用QGridLayout创建了一个跨三行和一列的小编辑器
layout->addWidget(smallEditor, 0, 2, 4, 1);
/* 对于QBoxLayout::addWidget()和QGridLayout::addWidget()函数,也可以添加最后一个参数来指定小部件的对齐方式。
* 默认情况下,它会填充整个单元格。但是,例如,我们可以将对齐方式指定为Qt::AlignRight,从而使小部件与右边缘对齐。*/
layout->setColumnStretch(1, 10); // 设置列的拉伸因子,决定了该列将超过或超过其必要最小值的可用空间的多少
layout->setColumnStretch(2, 20);
/* 我们为列1和列2设置拉伸因子。具有更高拉伸系数的列占用更多的可用空间。
* 因此,列2将获得比列1更多的可用空间,而列0根本不会增长,因为它的拉伸因子是0(默认值)。
* 列和行行为相同;对于行有一个等效的拉伸因子,以及一个QGridLayout::setRowStretch()函数。*/
gridGroupBox->setLayout(layout);
}
/* createFormGroupBox() 使用QFormLayout将对象整齐地安排到两个列中——名称和字段。*/
void Dialog::createFormGroupBox()
{
formGroupBox = new QGroupBox(tr("Form layout"));
QFormLayout *layout = new QFormLayout;
/* 用三个QLabel对象用于名称,三个对应的输入部件作为字段:QLineEdit、QComboBox和QSpinBox。
* 使用QFormLayout::addRow()将小部件添加到布局中。*/
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);
}