QT布局—基于Layout和QWidget的代码创建QT自适应布局(Size Policy和Stretch)

文章目录

    • 一、前言
    • 二、Widget与Layout
      • 2.1、Widget(窗口部件)
      • 2.2、Layout(布局)
    • 三、应用
      • 3.1、widget容器添加控件并布局
      • 3.2、自适应布局示例
      • 3.3、 垂直布局2:1分割布局
        • 3.3.1、方法1——控件大小策略
        • 3.3.2、方法2——布局setStretch方法
        • 3.3.3、方法3—— 布局addWidget方法
        • 3.3.4、方法4——QSplitter与布局结合

一、前言

  • 在Qt中,“layout”(布局)和"widget"(窗口部件)是两个相关但不同的概念。QWidget本身可以作为一个容器来容纳其他控件,而布局管理器则可以在这些容器中安排控件的位置。
  • 大小策略和stretch属性在Qt中都是非常有用的布局管理工具,可以帮助开发者精确地控制界面元素在布局中的大小和分布。大小策略主要用于定义控件自身的最小和最大尺寸行为,而stretch属性则用于在布局管理器中定义控件相对于其他控件的拉伸优先级,以实现动态的布局调整和分配。

二、Widget与Layout

2.1、Widget(窗口部件)

  1. 基本介绍
  • Widget是Qt中用户界面的基本构建块,是所有可见的用户界面元素的基类。
  • QWidget是QWidget类及其子类的实例,它们可以包含其他控件和部件,并且可以响应用户交互。常见的QWidget子类包括QPushButton、QLineEdit、QLabel等,它们用于显示和接收用户的输入或指示信息。
  • 每个QWidget通常都会有一个父窗口,可以通过构造函数参数或者后续设置来指定。
  • Widget 是Qt中用于构建用户界面的基本元素,QWidget即可作为控件也可以作为容器,作为容器的QWidget也可以像QDialog一样作为弹框。
  1. 布局相关
  • 控件的大小策略(Size Policies)
    • QSizePolicy::Fixed:固定大小,控件将保持其固定大小,不会随窗口大小改变而改变。
    • QSizePolicy::Preferred:优先大小,控件希望保持其首选大小,但可以根据布局管理器的需要进行调整。
    • QSizePolicy::Expanding:扩展大小,控件希望占用尽可能多的空间,可以随窗口的扩展而扩展。
    • QSizePolicy::Minimum 和 QSizePolicy::Maximum:最小和最大大小,控件将尽可能保持在指定的最小和最大尺寸范围内。
    // 创建一个子控件,例如QWidgets或其他需要放入布局中的控件
    QWidget *widget1 = new QWidget(&window);
    // 设置子控件的大小策略
    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    widget1->setSizePolicy(sizePolicy);  // 第一个控件占据更多空间
  • 布局的Stretch属性
    在布局管理器中,可以使用stretch属性来进一步控制控件在布局中的分配。Stretch属性定义了控件在布局中相对于其他控件拉伸的程度。当父布局容器的大小改变时,布局管理器根据各个控件的stretch属性决定如何分配额外的空间。
//(1)QHBoxLayout 和 QVBoxLayout 中的Stretch
QHBoxLayout *hLayout = new QHBoxLayout;
QPushButton *button1 = new QPushButton("Button 1");
QPushButton *button2 = new QPushButton("Button 2");
hLayout->addWidget(button1, 1);  // 指定按钮1的stretch为1
hLayout->addWidget(button2, 2);  // 指定按钮2的stretch为2
//在布局容器改变大小时,按钮2会获得比按钮1更多的额外空间。


//(2)QGridLayout 中的Stretch
//在网格布局(QGridLayout)中,可以使用 setRowStretch() 和 setColumnStretch() 方法来设置行或列的stretch属性
QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(button1, 0, 0);
gridLayout->addWidget(button2, 0, 1);
gridLayout->setColumnStretch(0, 1);  // 设置第0列的stretch为1
gridLayout->setColumnStretch(1, 2);  // 设置第1列的stretch为2

2.2、Layout(布局)

  1. 基本介绍
  • Layout是一种机制,用于管理一个或多个Widget在父Widget(通常是窗口或者另一个Widget)中的位置和大小。
  • 布局管理器负责自动安排子控件的位置和大小,以便它们能够自适应父容器的大小变化或者其他因素(如窗口尺寸、文本大小等)。
  • 布局管理器可以是水平布局(QHBoxLayout)、垂直布局(QVBoxLayout)、网格布局(QGridLayout)等。
  1. 布局相关
  • QBoxLayout的addStretch 和 setStretch
    QBoxLayout 是一个抽象基类,用于实现水平布局 (QHBoxLayout) 和垂直布局 (QVBoxLayout)。

    • addStretch
      addStretch是用来在布局中添加一个可伸缩的空白空间。这个空间会占据布局中剩余的空间,使得布局中的其他部件能够根据布局的规则进行分配。
    //在水平布局(QHBoxLayout)中使用addStretch会在布局中增加一个垂直伸展的空间,从而将其他部件推向布局的两端。
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(widget1);
    layout->addStretch(); // 添加伸缩空间
    layout->addWidget(widget2);
    
    • setStretch
      setStretch是用来设置布局中的伸缩因子(stretch factor),控制部件在布局中的大小分配。
    、、widget1和widget3将占据相等的空间,而widget2将占据两倍于其它两个部件的空间,因为它们的伸缩因子分别为12。
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(widget1);
    layout->addWidget(widget2);
    layout->addWidget(widget3);
    layout->setStretch(0, 1); // 设置第一个部件的伸缩因子为1
    layout->setStretch(1, 2); // 设置第二个部件的伸缩因子为2
    layout->setStretch(2, 1); // 设置第三个部件的伸缩因子为1	
    

三、应用

3.1、widget容器添加控件并布局

  • 步骤
  1. 创建自定义QWidget类: 首先,创建一个继承自QWidget的新类。这个类将充当你自定义的widget,你可以在其中定义自己的布局和其他控件。
  2. 添加布局管理器: 在自定义QWidget的构造函数中,创建并设置布局管理器。将布局管理器添加到QWidget中。
  3. 添加控件到布局中: 将你希望显示在自定义QWidget中的控件,例如按钮、文本框等,添加到布局管理器中。
  • 代码示例
//创建qwidget容器
QWidget window;
window.setWindowTitle("Layout Example");

// 创建按钮和布局管理器
QPushButton *button1 = new QPushButton("Button 1");
QPushButton *button2 = new QPushButton("Button 2");
QPushButton *button3 = new QPushButton("Button 3");

// 创建一个垂直布局管理器,并添加按钮
QVBoxLayout *vLayout = new QVBoxLayout(&window);
// 添加控件到布局
vLayout->addWidget(button1);
vLayout->addWidget(button2);

// 创建一个水平布局管理器,并添加按钮
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(button3);

// 将水平布局添加到垂直布局中
vLayout->addLayout(hLayout);

// 设置主窗口的布局
window.setLayout(vLayout);

3.2、自适应布局示例

  • 基本示例
    设定了布局管理器便可以使控件随布局大小改变而变化
QVBoxLayout *layout = new QVBoxLayout;
QWidget *widget = new QWidget;

QPushButton *button1 = new QPushButton("Button 1");
QPushButton *button2 = new QPushButton("Button 2");

layout->addWidget(button1);
layout->addWidget(button2);

widget->setLayout(layout);

注意事项

  • 布局管理器的选择:选择合适的布局管理器是实现自适应布局的关键。根据需要,可以使用水平布局、垂直布局或网格布局来管理窗口内部的控件。
  • 控件属性设置:有时需要设置控件的大小策略(size policy)或最小/最大大小,以确保它们在布局过程中按照期望的方式调整大小。
// 创建按钮
QPushButton *button1 = new QPushButton("Button 1", this);
QPushButton *button2 = new QPushButton("Button 2", this);
QPushButton *button3 = new QPushButton("Button 3", this);

// 设置按钮的大小策略
button1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

// 创建水平布局并添加按钮
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->addWidget(button1);
hLayout->addWidget(button2);
hLayout->addWidget(button3);

// 创建垂直布局
QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addLayout(hLayout);

// 设置主布局
setLayout(vLayout);

3.3、 垂直布局2:1分割布局

3.3.1、方法1——控件大小策略
// 创建主窗口和主布局
QWidget window;
QVBoxLayout *layout = new QVBoxLayout(&window);

// 创建两个子控件,例如QWidgets或其他需要放入布局中的控件
QWidget *widget1 = new QWidget(&window);
QWidget *widget2 = new QWidget(&window);

// 设置第一个控件的大小策略,占据两倍空间
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy1.setVerticalStretch(2); // 垂直方向上拉伸因子设置为2,占据两倍空间
widget1->setSizePolicy(sizePolicy1);

// 设置第二个控件的大小策略,占据一倍空间
QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy2.setVerticalStretch(1); // 垂直方向上拉伸因子设置为1,占据一倍空间
widget2->setSizePolicy(sizePolicy2);

// 添加子控件到布局中
layout->addWidget(widget1);
layout->addWidget(widget2);

// 设置主窗口的布局
window.setLayout(layout);
3.3.2、方法2——布局setStretch方法
QWidget window;
window.setWindowTitle("2:1 Vertical Layout Example");

// 创建一个垂直布局
QVBoxLayout *layout = new QVBoxLayout(&window);

// 创建两个Widget作为部件
QWidget *widget1 = new QWidget();
widget1->setStyleSheet("background-color: red;"); // 设置背景颜色以便区分
QWidget *widget2 = new QWidget();
widget2->setStyleSheet("background-color: green;"); // 设置背景颜色以便区分

// 将Widget添加到布局中
layout->addWidget(widget1);
layout->addWidget(widget2);

// 设置伸缩因子,实现2比1的布局
layout->setStretch(0, 2); // 第一个部件的伸缩因子为2
layout->setStretch(1, 1); // 第二个部件的伸缩因子为1
3.3.3、方法3—— 布局addWidget方法
QVBoxLayout *vbox = new QVBoxLayout(this);
// 创建两个子控件(QWidget)
QWidget *widget1 = new QWidget(this);
QWidget *widget2 = new QWidget(this);
// 设置背景颜色以便区分各个子控件
widget1->setStyleSheet("background-color: lightblue;");
widget2->setStyleSheet("background-color: lightgreen;");
// 将子控件添加到垂直布局中,并设置 stretch 因子
vbox->addWidget(widget1, 2); // stretch factor 2
vbox->addWidget(widget2, 1); // stretch factor 1
// 设置布局管理器
setLayout(vbox);
3.3.4、方法4——QSplitter与布局结合

QSplitter

  1. 定义
  • QSplitter 是一个控件,用于在用户界面中创建可调整大小的分割窗格。它允许用户通过拖动分隔条来调整包含的子部件的大小。
  • QSplitter 不是布局管理器,而是一种容器,可以嵌套在布局管理器中使用,用于管理其中的子部件的大小和位置。
  • 通过 addWidget方法,可以向 QSplitter 中添加子部件,并通过 setSizes 方法来手动设置每个子部件的大小。
  1. 与QBoxLayout关系
  • 使用场景:通常情况下,你会在用户界面中使用 QBoxLayout 来安排和管理控件的布局。如果希望在布局中创建可调整大小的分割窗格,可以将 QSplitter 嵌套在 QBoxLayout 中的一个或多个部件中。
  • 嵌套关系:例如,可以创建一个垂直布局 (QVBoxLayout),在其中添加一个 QSplitter,然后向 QSplitter 中添加子部件。这样可以在垂直布局中创建多个可调整大小的区域。
  • 协同使用:在实际的界面设计中,QSplitter 和 QBoxLayout 可以协同工作,以实现复杂的布局需求。例如,一个水平布局中可能包含一个垂直的 QSplitter,在其中又包含多个水平或垂直布局。
// 创建主窗口
QWidget mainWindow;
mainWindow.setWindowTitle("QSplitter with Layout Example");
mainWindow.resize(600, 400);

// 创建垂直布局管理器
QVBoxLayout *mainLayout = new QVBoxLayout(&mainWindow);

// 创建 QSplitter
QSplitter *splitter = new QSplitter(Qt::Vertical);

// 创建两个文本编辑器作为 QSplitter 的子部件
QTextEdit *textEdit1 = new QTextEdit;
QTextEdit *textEdit2 = new QTextEdit;

// 将子部件添加到 QSplitter 中
splitter->addWidget(textEdit1);
splitter->addWidget(textEdit2);

// 设置子部件的初始大小比例,2:1
splitter->setSizes(QList<int>() << 2 << 1);

// 将 QSplitter 添加到主布局中
mainLayout->addWidget(splitter);

// 设置主窗口的布局
mainWindow.setLayout(mainLayout);

// 显示主窗口
mainWindow.show();
### 如何在Qt Designer中实现按钮自适应布局 #### 创建项目并打开Qt Designer 为了创建一个具有自适应功能的按钮布局,在Qt Designer中新建或打开现有UI文件。 #### 添加控件至表单 通过拖拽的方式向主窗口添加所需的`QPushButton`其他必要的组件。这一步骤允许直观地构建用户界面的基础结构[^1]。 #### 应用布局管理器 对于希望水平排列的一组按钮,可以选择这两个按钮然后点击工具栏中的“Lay out Horizontally in a Box Layout”图标来应用`QHBoxLayout`; 对于垂直排列,则应选择“Lay out Vertically in a Box Layout”。这样做之后,所选的小部件会被放置在一个不可见容器内,并按照指定的方向进行排列[^2]。 #### 设置拉伸因子与间距属性 为了让按钮能够更好地响应窗口大小的变化,可以通过右键菜单访问每个按钮的属性编辑器,调整它们之间的空间分配以及边缘留白。特别是设置合适的`spacing``stretch factor`可以帮助改善视觉效果用户体验[^3]。 #### 测试自适应行为 完成上述配置后,可以在Qt Designer内部预览不同尺寸下的表现情况。如果一切正常工作的话,当改变窗体宽度时,所有子项都会相应移动位置保持良好的外观比例;同样地,高度方向也会如此反应。此外,还可以利用`QWidget::setSizePolicy()`函数进一步微调各个小部件的增长策略[^4]。 ```cpp // C++代码示例:为按钮设置size policy以增强灵活性 ui->pushButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LoserChaser

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

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

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

打赏作者

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

抵扣说明:

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

余额充值