OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2413|回复: 0

《I.MX6U 嵌入式Qt开发指南》第七章 Qt控件 7.5 布局管理

[复制链接]

1061

主题

1072

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4407
金钱
4407
注册时间
2019-5-8
在线时间
1196 小时
发表于 2022-7-29 09:52:52 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2022-7-29 09:51 编辑

1)实验平台:正点原子阿尔法Linux开发板
2)  章节摘自【正点原子】《I.MX6U 嵌入式Qt开发指南》

3)购买链接:https://detail.tmall.com/item.htm?id=609033604451
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子阿尔法Linux交流群:1027879335




第七章 Qt控件

7.5 布局管理
Qt提供了非常丰富的布局类,基本布局管理类包括:QBoxLayout、QGridLayout、QFormLayout和QStackedLayout。这些类都从QLayout继承而来,它们都来源于QObject(而不是QWidget)。创建更加复杂的布局,可以让它们彼此嵌套完成。
其中QBoxLayout提供了水平和垂直的布局管理;QFormLayout提供了将输入部件和标签成组排列的布局管理;QGridLayout提供了网格形式的布局管理;QStackedLayout提供了一组布局后的部件,可以对它们进行分布显示。
它们的继承关系如下图。
image002.png
下面将学习Layouts组里面的4种布局,如下图。
image004.jpg

各个控件的名称依次解释如下。
(1)           Vertiacl Layout:垂直布局
(2)           Horizontal Layout:水平布局
(3)           Grid Layout:网格布局
(4)           Form Layout:表单布局
QBoxLayout继承QLayout。QBoxLayout类提供水平或垂直地排列子部件。QBoxLayout获取从它的父布局或从parentWidget()中所获得的空间,将其分成一列框,并使每个托管小部件填充一个框。
QGridLayout继承QLayout。QGridLayout获取可用的空间(通过其父布局或parentWidget())),将其分为行和列,并将其管理的每个小部件放入正确的单元格中。由于网格布局管理器中的组件也是会随着窗口拉伸而发生变化的,所以也是需要设置组件之间的比例系数的,与QBoxLayout不同的是网格布局管理器还需要分别设置行和列的比例系数。
QFormLayout继承QLayout。QFormLayout类管理输入小部件及其关联标签的表单。QFormLayout是一个方便的布局类,它以两列的形式布局其子类。左列由标签组成,右列由“字段”小部件(QLineEdit(行编辑器)、QSpinBox(旋转框等))组成。通常使用setRowWrapPolicy(RowWrapPolicy policy)接口函数设置布局的换行策略进行布局等。

7.5.1 QBoxLayout7.5.1.1 控件简介
QBoxLayout继承QLayout。QBoxLayout类提供水平或垂直地排列子部件。QBoxLayout获取从它的父布局或从parentWidget()中所获得的空间,将其分成一列框,并使每个托管小部件填充一个框。
7.5.1.2 用法示例
例29_qboxlayout,垂直或水平布局(难度:简单),使用几个按钮,将他们设置为垂直排布和水平排布,以及设置它们的一些属性。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成如下图。
image006.jpg
   在头文件mainwindow.h”具体代码如下。
  1. mainwindow.h编程后的代码
  2. 1   #ifndef MAINWINDOW_H
  3. 2   #define MAINWINDOW_H
  4. 3
  5. 4   #include <QMainWindow>
  6. 5   #include <QHBoxLayout>
  7. 6   #include <QVBoxLayout>
  8. 7   #include <QPushButton>
  9. 8
  10. 9   class MainWindow : public QMainWindow
  11. 10  {
  12. 11      Q_OBJECT
  13. 12
  14. 13  public:
  15. 14      MainWindow(QWidget *parent = nullptr);
  16. 15      ~MainWindow();
  17. 16
  18. 17  private:
  19. 18      /* 声明按钮对象数组 */
  20. 19      QPushButton *pushButton[6];
  21. 20
  22. 21      /* 定义两个widget,用于容纳排布按钮 */
  23. 22      QWidget *hWidget;
  24. 23      QWidget *vWidget;
  25. 24
  26. 25      /* QHBoxLayout与QVBoxLayout对象 */
  27. 26      QHBoxLayout *hLayout;
  28. 27      QVBoxLayout *vLayout;
  29. 28
  30. 29  };
  31. 30  #endif // MAINWINDOW_H
复制代码
在源文件“mainwindow.cpp”具体代码如下。
  1. mainwindow.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2   #include <QList>
  4. 3
  5. 4   MainWindow::MainWindow(QWidget *parent)
  6. 5       : QMainWindow(parent)
  7. 6   {
  8. 7       /* 设置主窗口的位置与大小 */
  9. 8       this->setGeometry(0, 0, 800, 480);
  10. 9
  11. 10      /* 实例化与设置位置大小 */
  12. 11      hWidget = new QWidget(this);
  13. 12      hWidget->setGeometry(0, 0, 800, 240);
  14. 13
  15. 14      vWidget = new QWidget(this);
  16. 15      vWidget->setGeometry(0, 240, 800, 240);
  17. 16
  18. 17      hLayout = new QHBoxLayout();
  19. 18      vLayout = new QVBoxLayout();
  20. 19
  21. 20      /* QList<T>是Qt的一种泛型容器类。
  22. 21       * 它以链表方式存储一组值,
  23. 22       * 并能对这组数据进行快速索引
  24. 23       */
  25. 24      QList <QString>list;
  26. 25      /* 将字符串值插入list */
  27. 26      list<<"one"<<"two"<<"three"<<"four"<<"five"<<"six";
  28. 27
  29. 28      /* 用一个循环实例化6个按钮 */
  30. 29      for(int i = 0; i < 6; i++){
  31. 30          pushButton[i] = new QPushButton();
  32. 31          pushButton[i]->setText(list[i]);
  33. 32          if(i < 3) {
  34. 33              /* 将按钮添加至hLayout中 */
  35. 34              hLayout->addWidget(pushButton[i]);
  36. 35          } else {
  37. 36              /* 将按钮添加至vLayout中 */
  38. 37              vLayout->addWidget(pushButton[i]);
  39. 38          }
  40. 39      }
  41. 40      /* 设置间隔为50 */
  42. 41      hLayout->setSpacing(50);
  43. 42
  44. 43      /* hWidget与vWidget的布局设置为hLayout/vLayout */
  45. 44      hWidget->setLayout(hLayout);
  46. 45      vWidget->setLayout(vLayout);
  47. 46  }
  48. 47
  49. 48  MainWindow::~MainWindow()
  50. 49  {
  51. 50  }
复制代码
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2
  4. 3   #include <QApplication>
  5. 4
  6. 5   int main(int argc, char *argv[])
  7. 6   {
  8. 7       QApplication a(argc, argv);
  9. 8       MainWindow w;
  10. 9       w.show();
  11. 10      return a.exec();
  12. 11  }
复制代码


7.5.1.3 运行效果
程序编译运行的结果如下。可以看到在hWidget中添加了3个水平排布的按钮,在vWidget中添加了3个垂直排布的按钮。
image008.jpg


7.5.2 QGridLayout
7.5.2.1 控件简介
QGridLayout类提供了布局管理器里的一种以网格(二维)的方式管理界面组件,以按钮组件为例,它们所对应网格的坐标下表,与二维数组类似。
4AC4DABD-FD8F-467c-B53A-14659C633AAE.png
QGridLayout继承QLayout。QGridLayout获取可用的空间(通过其父布局或parentWidget())),将其分为行和列,并将其管理的每个小部件放入正确的单元格中。由于网格布局管理器中的组件也是会随着窗口拉伸而发生变化的,所以也是需要设置组件之间的比例系数的,与QBoxLayout不同的是网格布局管理器还需要分别设置行和列的比例系数。

7.5.2.2 用法示例
例30_qgridlayout,网格布局(难度:简单),使用几个按钮,将他们设置为网格布局,同时设置它们的行、列比例系数(拉伸因子),以及设置它们的一些属性。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成如下图。
   在头文件“mainwindow.h”具体代码如下。
  1. mainwindow.h编程后的代码
  2. 1   #ifndef MAINWINDOW_H
  3. 2   #define MAINWINDOW_H
  4. 3
  5. 4   #include <QMainWindow>
  6. 5   #include <QGridLayout>
  7. 6   #include <QPushButton>
  8. 7
  9. 8   class MainWindow : public QMainWindow
  10. 9   {
  11. 10      Q_OBJECT
  12. 11
  13. 12  public:
  14. 13      MainWindow(QWidget *parent = nullptr);
  15. 14      ~MainWindow();
  16. 15  private:
  17. 16
  18. 17      /* 声明widget窗口部件,用于容纳下面4个pushButton按钮 */
  19. 18      QWidget *gWidget;
  20. 19
  21. 20      /* 声明QGridLayout对象 */
  22. 21      QGridLayout *gridLayout;
  23. 22
  24. 23      /* 声明pushButton按钮数组 */
  25. 24      QPushButton *pushButton[4];
  26. 25
  27. 26  };
  28. 27  #endif // MAINWINDOW_H
复制代码
在源文件“mainwindow.cpp”具体代码如下。
  1. mainwindow.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2
  4. 3   MainWindow::MainWindow(QWidget *parent)
  5. 4       : QMainWindow(parent)
  6. 5   {
  7. 6       /* 设置位置与大小 */
  8. 7       this->setGeometry(0, 0, 800, 480);
  9. 8
  10. 9       /* 实例化 */
  11. 10      gWidget = new QWidget(this);
  12. 11      /* 设置gWidget居中央 */
  13. 12      this->setCentralWidget(gWidget);
  14. 13
  15. 14      gridLayout = new QGridLayout();
  16. 15      /* QList链表,字符串类型 */
  17. 16      QList <QString> list;
  18. 17      list<<"按钮1"<<"按钮2"<<"按钮3"<<"按钮4";
  19. 18      for (int i = 0; i < 4; i++){
  20. 19          pushButton[i] = new QPushButton();
  21. 20          pushButton[i]->setText(list[i]);
  22. 21          /* 设置最小宽度与高度 */
  23. 22          pushButton[i]->setMinimumSize(100, 30);
  24. 23          /* 自动调整按钮的大小 */
  25. 24          pushButton[i]->setSizePolicy(
  26. 25                      QSizePolicy::Expanding,
  27. 26                      QSizePolicy::Expanding
  28. 27                      );
  29. 28          switch (i) {
  30. 29          case 0:
  31. 30              /* 将pushButton[0]添加至网格的坐标(0,0),下同 */
  32. 31              gridLayout->addWidget(pushButton[i], 0, 0);
  33. 32              break;
  34. 33          case 1:
  35. 34              gridLayout->addWidget(pushButton[i], 0, 1);
  36. 35              break;
  37. 36          case 2:
  38. 37              gridLayout->addWidget(pushButton[i], 1, 0);
  39. 38              break;
  40. 39          case 3:
  41. 40              gridLayout->addWidget(pushButton[i], 1, 1);
  42. 41              break;
  43. 42          default:
  44. 43              break;
  45. 44          }
  46. 45      }
  47. 46      /* 设置第0行与第1行的行比例系数 */
  48. 47      gridLayout->setRowStretch(0, 2);
  49. 48      gridLayout->setRowStretch(1, 3);
  50. 49
  51. 50      /* 设置第0列与第1列的列比例系数 */
  52. 51      gridLayout->setColumnStretch(0, 1);
  53. 52      gridLayout->setColumnStretch(1, 3);
  54. 53
  55. 54      /* 将gridLayout设置到gWidget */
  56. 55      gWidget->setLayout(gridLayout);
  57. 56  }
  58. 57
  59. 58  MainWindow::~MainWindow()
  60. 59  {
  61. 60  }
复制代码

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2
  4. 3   #include <QApplication>
  5. 4
  6. 5   int main(int argc, char *argv[])
  7. 6   {
  8. 7       QApplication a(argc, argv);
  9. 8       MainWindow w;
  10. 9       w.show();
  11. 10      return a.exec();
  12. 11  }
复制代码
7.5.2.3 运行效果
程序编译运行的结果如下。可以看到在gWidget中添加了4个按钮,因为设置了行、列的系数比(拉伸因子),所以看到的按钮是按系数比的比例显示。
image012.jpg


7.5.3 QFormLayout
7.5.3.1 控件简介
QFormLayout继承QLayout。QFormLayout类管理输入小部件及其关联标签的表单。QFormLayout是一个方便的布局类,它以两列的形式布局其子类。左列由标签组成,右列由“字段”小部件(QLineEdit(行编辑器)、QSpinBox(旋转框等))组成。通常使用setRowWrapPolicy(RowWrapPolicy policy)接口函数设置布局的换行策略进行布局等。
7.5.3.2 用法示例
例31_qformlayout,表单布局(难度:简单),将使用addRow(const QString &labelText, QWidget *field)来创建一个带有给定文本的QLabel及QWidget小部件,并且它们是伙伴关系。简单的展示表单布局的使用。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成如下图。
image014.jpg
在源文件“mainwindow.cpp”具体代码如下。

  1. mainwindow.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2
  4. 3   MainWindow::MainWindow(QWidget *parent)
  5. 4       : QMainWindow(parent)
  6. 5   {
  7. 6       /* 设置位置与大小 */
  8. 7       this->setGeometry(0, 0, 800, 480);
  9. 8
  10. 9       /* 实例化及设置位置与大小,下同 */
  11. 10      fWidget = new QWidget(this);
  12. 11      fWidget->setGeometry(250, 100, 300, 200);
  13. 12
  14. 13      userLineEdit = new QLineEdit();
  15. 14      passwordLineEdit = new QLineEdit();
  16. 15
  17. 16      formLayout = new QFormLayout();
  18. 17
  19. 18      /* 添加行 */
  20. 19      formLayout->addRow("用户名:", userLineEdit);
  21. 20      formLayout->addRow("密码    :", passwordLineEdit);
  22. 21
  23. 22      /* 设置水平垂直间距 */
  24. 23      formLayout->setSpacing(10);
  25. 24
  26. 25      /* 设置布局外框的宽度 */
  27. 26      formLayout->setMargin(20);
  28. 27
  29. 28      /* 将formLayout布局到fWidget */
  30. 29      fWidget->setLayout(formLayout);
  31. 30  }
  32. 31
  33. 32  MainWindow::~MainWindow()
  34. 33  {
  35. 34  }
复制代码

在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码
  2. 1   #include "mainwindow.h"
  3. 2
  4. 3   #include <QApplication>
  5. 4
  6. 5   int main(int argc, char *argv[])
  7. 6   {
  8. 7       QApplication a(argc, argv);
  9. 8       MainWindow w;
  10. 9       w.show();
  11. 10      return a.exec();
  12. 11  }
复制代码

7.5.3.3 运行效果
       程序编译运行的结果如下。可以看到在fWidget中添加了两行,同时设置了它们的间隔,与距边框的宽度。与QGirdLayout布局比较,QFomLayout布局比较适用于行与列比较少的布局格局。如果是多行多列的布局,应该使用QGirdLayout布局。
image016.jpg



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 04:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表