布局类(101):【例】Basic Layouts Example [官翻]

Basic Layouts Example

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

基本布局显示如何使用Qt中提供的标准布局管理器:QBoxLayout、QGridLayout和QFormLayout。Screenshot of the Basic Layouts example

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值