【QT学习三】Qt 的基本布局类QLayout

目录

一、简述

二、详解

1、QBoxLayout

2、QGridLayout

3、QFormLayout

4、QStackedLayout


一、简述

QLayout类是布局管理器的基类。

QLayout是由具体类 QBoxLayout、QGridLayout、QFormLayout 和 QStackedLayout继承的抽象基类。

Qlayout类是抽象类,所以不可以被实例化。

下图是类的继承关系图:

QLayoutItem类提供QLayout操作的抽象项。

Qlayout的管理又是以QLayoutItem为单位。所以,在addWidget的操作中,QLayout会创建一个QLayoutItem的子类。QWidgetItem类来对应的包装代理添加进来的子控件。QWidgetItem对象最终会将QLayout布局管理体系中的布局参数信息装换、设置到它所代理的QWidget对象上。

所有 QWidget子类都可以使用布局来管理它们的子类。QWidget::setLayout()函数可以为一个控件布局。如果QWidget上已经设置了布局管理器,QWidget将不允许您安装另一个。必须先删除现有布局管理器(由layout()返回),然后才能使用新布局调用setLayout()。

当以这种方式在widget上设置布局时,它负责以下任务:

1、布置子控件。

2、最高层窗口可感知的默认大小。

3、最高层窗口可感知的最小大小。

4、调整大小的处理。

5、当内容改变的时候自动更新:

字体大小、文本或者子控件的其它内容。

隐藏或者显示子控件。

移除一些子控件。

注意:布局销毁后,布局内的控件不会被销毁,控件不能以布局作为parent。

可以在布局中使用addLayout()来嵌套布局,内部的布局就会变成它的子布局。

二、详解

1、QBoxLayout

QBoxLayout类水平或垂直排列子部件(widget或layout)。QBoxLayout将它获得的空间分成一行小框框,每一个小框托管一个子部件。

创建QBoxLayout的最简单方法是使用它的一个子类,例如QHBoxLayout(水平布局)或QVBoxLayout(垂直布局)。也可以直接使用QBoxLayout构造函数,将其方向指定为LeftToRight、RightToLeft、TopToBottom或BottomToTop。

enum QBoxLayout::Direction

Constant

Value

Description

QBoxLayout::LeftToRight

0

水平从左到右

QBoxLayout::RightToLeft

1

水平从右到左

QBoxLayout::TopToBottom

2

垂直从上到下

QBoxLayout::BottomToTop

3

垂直从下到上

如果QBoxLayout不是顶级布局(即它没有管理小部件的所有区域和子项),则必须将其添加到其父布局中,然后才能对其进行任何操作。添加布局的常规方法是调用parentLayout->addLayout()。

可以使用以下四个方法之一将部件加到QBoxLayout:

  • addWidget(QWidget *widget, int stretch = 0,Qt::Alignment alignment = Qt::Alignment())

将小部件添加到QBoxLayout并设置小部件的拉伸因子和对齐方式。(默认对齐方式为0,这意味着小部件将填充整个单元格。)

  • addSpacing(int size)

将大小为的不可拉伸空间(QSpacerItem)添加到此框布局的末尾。QBoxLayout提供默认边距和间距。此功能可增加额外空间。

  • addStretch(int stretch = 0)

将最小大小和拉伸系数为零的可拉伸空间(QSpacerItem)添加到此框布局的末尾。

  • addLayout(QLayout *layout, int stretch = 0)

将包含另一个QLayout的框添加到布局的末尾,并设置该布局的拉伸因子。

另外还可以使用insertWidget()、insertSpacing()、insertStretch()或insertLayout()在布局中的指定位置插入框。

QBoxLayout还包括两种边距宽度:

setContentsMargins()设置小部件每一侧的外边框宽度。这是沿QBoxLayout四边的保留空间的宽度。

setSpacing()设置相邻框之间的宽度。(您可以使用addSpacing()在特定位置获得更多空间。)

注意:边距默认值由样式提供。大多数Qt样式指定的默认边距为9(子窗口小部件)和11(窗口)。间距默认为与顶层布局的边距宽度相同,或与父布局相同。

要从布局中删除小部件,请调用removeWidget()。在小部件上调用Qwidget::hide()也会有效地从布局中移除小部件,直到调用Qwidget::show()。

实例:


    QWidget *window = new QWidget;
    QPushButton *button1 = new QPushButton("One");
    QPushButton *button2 = new QPushButton("Two");
    QPushButton *button3 = new QPushButton("Three");
    QPushButton *button4 = new QPushButton("Four");
    QPushButton *button5 = new QPushButton("Five");
 
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);
    layout->addWidget(button4);
    layout->addWidget(button5);
 
    window->setLayout(layout);
    window->show();

首先,我们在布局中创建所需的小部件。然后,我们创建QHBoxLayout对象并将小部件添加到布局中。最后,我们调用QWidget::setLayout()将QHBoxLayout对象安装到小部件上。此时,布局中的小部件将被重新编程,以将窗口作为其父窗口。

如果我们创建QVBoxLayout对象去添加小部件,效果如下:

2、QGridLayout

QGridLayout将其获得的空间划分为行和列,并将其管理的每个小部件放入正确的单元格中。

每列都有最小宽度和拉伸系数。最小宽度是使用setColumnMinimumWidth()设置的最大宽度,也是该列中每个小部件的最小宽度。拉伸因子是使用setColumnStretch()设置的,它决定了该列将获得多少可用空间并超过其所需的最小值。

列和行的行为相同,行也有相应的函数设置最小宽度和拉伸系数。

通常,使用addWidget()或addLayout()将每个托管小部件或布局放入其自己的单元格中。

void QGridLayout::addLayout(QLayout*layout, int row, int column, Qt::Alignment alignment = Qt::Alignment())

void QGridLayout::addWidget(QWidget*widget, int row, int column, Qt::Alignment alignment = Qt::Alignment())

将给定的小部件或布局添加到单元格网格的某行、某列。默认情况下,左上角位置为(0,0)。默认对齐方式为0,这意味着小部件将填充整个单元格。

void QGridLayout::addLayout(QLayout*layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignmentalignment = Qt::Alignment())

void QGridLayout::addWidget(QWidget*widget, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment= Qt::Alignment())

这两个都是重载函数。将小部件或布局添加到单元格网格中,跨越多行/多列。单元格将从row、column开始,跨越rowSpan行和columnSpan列。小部件将具有给定的对齐方式。如果rowSpan和/或columnSpan为-1,则小部件或布局将分别延伸到底部和/或右边缘。

要从布局中删除小部件,请调用removeWidget()。在小部件上调用QWidget::hide()也会有效地从布局中移除小部件,直到调用QWidget::show()。

QGridLayout还包括两个页边空白宽度:ContentsMargins和spacing()。ContentsMargins是QGridLayout四条边上保留空间的宽度。spacing()是相邻框之间自动分配的间距的宽度。

函数spacing():如果垂直间距等于水平间距,则此函数返回该值;否则返回-1。

通常情况下我们使用verticalSpacing()和horizontalSpacing(),相应的也有set函数。

注意:默认内容边距值由样式提供。Qt样式指定的默认值是9(对于子窗口小部件)和11(对于窗口)。间距默认为与顶层布局的边距宽度相同,或与父布局相同。

实例:


MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
 
   if(this->centralWidget())    {
      delete this->centralWidget();
    }
 
   QWidget *cWidget = new QWidget(this);
   this->setCentralWidget(cWidget);
 
   QGridLayout *glayout = new QGridLayout();
   QStringList text = {"7", "8", "9","4", "5", "6", "1", "2","3","+/-","0","."};
    int idx = 0;
   for (int i = 0; i < 4; i++)
    {
       for (int j = 0; j < 3; j++)
       {
           idx = i * 3 + j;
           QPushButton *btn = new QPushButton(text.at(idx));
           glayout->addWidget(btn, i, j);
       }
    }
   cWidget->setLayout(glayout);
}

实现了一个数字小键盘界面,效果如下:

3、QFormLayout

QFormLayout以两列形式布局其子项。左列由标签组成,右列由小部件组成。

QGridLayout也能实现两列形式的布局,但QFormLayout有它独特的优点:

  1. 遵循不同平台的外观和行为准则。

例如,macOS和KDE默认标签应该右对齐,而Windows和GNOME应用程序通常使用左对齐。

  1. 支持包裹长行。

对于具有小型显示器的设备,QFormLayout可以设置为换行长行,甚至换行所有行。

  1. 用于创建“标签-字段”的API。

addRow()重载使用QString和QWidget*在后台创建一个QLabel,并自动设置其好友。

例如:


        QFormLayout*formLayout = new QFormLayout;
         formLayout->addRow(tr("&Name:"),nameLineEdit);
         formLayout->addRow(tr("&Email:"),emailLineEdit);
         formLayout->addRow(tr("&Age:"),ageSpinBox);
        setLayout(formLayout);

4、QStackedLayout

QStackedLayout类提供了一组小部件,一次只能看到一个小部件。

QStackedLayout可用于创建与QTabWidget提供的用户界面类似的用户界面。在QStackedLayout之上还构建了一个方便的QStackeedWidget类。

基于以上原因,QStackedLayout在一般项目中很少使用。

代码实例:


MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
 
   if(this->centralWidget())    {
      delete this->centralWidget();
    }
 
   QWidget *cWidget = new QWidget(this);
   this->setCentralWidget(cWidget);
 
   QWidget *firstPageWidget = new QWidget;
   firstPageWidget->setStyleSheet("background:rgb(0,255,0);");
   QWidget *secondPageWidget = new QWidget;
   secondPageWidget->setStyleSheet("background:rgb(255,255,0);");
   QWidget *thirdPageWidget = new QWidget;
   thirdPageWidget->setStyleSheet("background:rgb(0,255,255);");
 
   QStackedLayout *stackedLayout = new QStackedLayout;
   stackedLayout->addWidget(firstPageWidget);
   stackedLayout->addWidget(secondPageWidget);
   stackedLayout->addWidget(thirdPageWidget);
 
   QComboBox *pageComboBox = new QComboBox;
   pageComboBox->addItem(tr("Page 1"));
   pageComboBox->addItem(tr("Page 2"));
   pageComboBox->addItem(tr("Page 3"));
   connect(pageComboBox,QOverload<int>::of(&QComboBox::activated),
           stackedLayout, &QStackedLayout::setCurrentIndex);
 
    QVBoxLayout *mainLayout = new QVBoxLayout;
   mainLayout->addWidget(pageComboBox);
   mainLayout->addLayout(stackedLayout);
   cWidget->setLayout(mainLayout);
}

每个widget设置了不同的背景色,通过选择不同项,显示不同widget,效果如下:

在Qt中,layoutSizeConstraint是用于控制布局的大小约束的属性。它可以设置在布局中的小部件大小发生变化时,布局的行为。

layoutSizeConstraint是一个枚举类型,它有以下几个选项:

  • QLayout::SetDefaultConstraint:默认约束。布局将按照其内容和部件的最小尺寸进行调整。

  • QLayout::SetFixedSize:固定大小约束。布局的大小将被固定,不会根据内容和部件的大小进行调整。

  • QLayout::SetMinimumSize:最小尺寸约束。布局的大小将根据内容和部件的最小尺寸进行调整,但不会超过布局的最小尺寸。

  • QLayout::SetMaximumSize:最大尺寸约束。布局的大小将根据内容和部件的大小进行调整,但不会超过布局的最大尺寸。

  • QLayout::SetMinAndMaxSize:最小和最大尺寸约束。布局的大小将根据内容和部件的大小进行调整,但会受到布局的最小和最大尺寸的限制。

可以使用以下方法来设置布局的大小约束:

QLayout *layout = new QHBoxLayout;

layout->setSizeConstraint(QLayout::SetFixedSize);

上述示例将布局的大小约束设置为固定大小,这意味着布局的大小将保持不变,不会根据内容和部件的大小进行调整。

在实际使用中,根据布局的需求和应用场景选择合适的大小约束,以便获得所期望的布局行为

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从此不归路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值