简述

QBorderLayout,顾名思义-边框布局,实现了排列子控件包围中央区域的布局。

具体实现要求不再赘述,请参考前几节内容。

实现

QBorderLayout主要采用QLayout和QWidgetItem实现,而窗口使用了QWidget,中央窗体使用QTextBrowser,四周以QLabel排列。

效果

源码

QBorderLayout.h

  1. #ifndef QBORDERLAYOUT_H
  2. #define QBORDERLAYOUT_H
  3. #include <QLayout>
  4. #include <QRect>
  5. class QBorderLayout : public QLayout
  6. {
  7. public:
  8. enum Position {West, North, South, East, Center};
  9. explicit QBorderLayout(QWidget *parent, int margin = 0, int spacing = -1);
  10. QBorderLayout(int spacing = -1);
  11. ~QBorderLayout();
  12. void addItem(QLayoutItem *item) Q_DECL_OVERRIDE;
  13. void addWidget(QWidget *widget, Position position);
  14. Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
  15. bool hasHeightForWidth() const Q_DECL_OVERRIDE;
  16. int count() const Q_DECL_OVERRIDE;
  17. QLayoutItem *itemAt(int index) const Q_DECL_OVERRIDE;
  18. QSize minimumSize() const Q_DECL_OVERRIDE;
  19. void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
  20. QSize sizeHint() const Q_DECL_OVERRIDE;
  21. QLayoutItem *takeAt(int index) Q_DECL_OVERRIDE;
  22. void add(QLayoutItem *item, Position position);
  23. private:
  24. struct ItemWrapper
  25. {
  26. ItemWrapper(QLayoutItem *i, Position p) {
  27. item = i;
  28. position = p;
  29. }
  30. QLayoutItem *item;
  31. Position position;
  32. };
  33. enum SizeType { MinimumSize, SizeHint };
  34. QSize calculateSize(SizeType sizeType) const;
  35. QList<ItemWrapper *> list;
  36. };
  37. #endif // QBORDERLAYOUT_H

QBorderLayout.cpp

  1. #include "QBorderLayout.h"
  2. QBorderLayout::QBorderLayout(QWidget *parent, int margin, int spacing)
  3. : QLayout(parent)
  4. {
  5. setMargin(margin);
  6. setSpacing(spacing);
  7. }
  8. QBorderLayout::QBorderLayout(int spacing)
  9. {
  10. setSpacing(spacing);
  11. }
  12. QBorderLayout::~QBorderLayout()
  13. {
  14. QLayoutItem *l;
  15. while ((l = takeAt(0)))
  16. delete l;
  17. }
  18. void QBorderLayout::addItem(QLayoutItem *item)
  19. {
  20. add(item, West);
  21. }
  22. void QBorderLayout::addWidget(QWidget *widget, Position position)
  23. {
  24. add(new QWidgetItem(widget), position);
  25. }
  26. Qt::Orientations QBorderLayout::expandingDirections() const
  27. {
  28. return Qt::Horizontal | Qt::Vertical;
  29. }
  30. bool QBorderLayout::hasHeightForWidth() const
  31. {
  32. return false;
  33. }
  34. int QBorderLayout::count() const
  35. {
  36. return list.size();
  37. }
  38. QLayoutItem *QBorderLayout::itemAt(int index) const
  39. {
  40. ItemWrapper *wrapper = list.value(index);
  41. if (wrapper)
  42. return wrapper->item;
  43. else
  44. return 0;
  45. }
  46. QSize QBorderLayout::minimumSize() const
  47. {
  48. return calculateSize(MinimumSize);
  49. }
  50. void QBorderLayout::setGeometry(const QRect &rect)
  51. {
  52. ItemWrapper *center = 0;
  53. int eastWidth = 0;
  54. int westWidth = 0;
  55. int northHeight = 0;
  56. int southHeight = 0;
  57. int centerHeight = 0;
  58. int i;
  59. QLayout::setGeometry(rect);
  60. for (i = 0; i < list.size(); ++i) {
  61. ItemWrapper *wrapper = list.at(i);
  62. QLayoutItem *item = wrapper->item;
  63. Position position = wrapper->position;
  64. if (position == North) {
  65. item->setGeometry(QRect(rect.x(), northHeight, rect.width(),
  66. item->sizeHint().height()));
  67. northHeight += item->geometry().height() + spacing();
  68. } else if (position == South) {
  69. item->setGeometry(QRect(item->geometry().x(),
  70. item->geometry().y(), rect.width(),
  71. item->sizeHint().height()));
  72. southHeight += item->geometry().height() + spacing();
  73. item->setGeometry(QRect(rect.x(),
  74. rect.y() + rect.height() - southHeight + spacing(),
  75. item->geometry().width(),
  76. item->geometry().height()));
  77. } else if (position == Center) {
  78. center = wrapper;
  79. }
  80. }
  81. centerHeight = rect.height() - northHeight - southHeight;
  82. for (i = 0; i < list.size(); ++i) {
  83. ItemWrapper *wrapper = list.at(i);
  84. QLayoutItem *item = wrapper->item;
  85. Position position = wrapper->position;
  86. if (position == West) {
  87. item->setGeometry(QRect(rect.x() + westWidth, northHeight,
  88. item->sizeHint().width(), centerHeight));
  89. westWidth += item->geometry().width() + spacing();
  90. } else if (position == East) {
  91. item->setGeometry(QRect(item->geometry().x(), item->geometry().y(),
  92. item->sizeHint().width(), centerHeight));
  93. eastWidth += item->geometry().width() + spacing();
  94. item->setGeometry(QRect(
  95. rect.x() + rect.width() - eastWidth + spacing(),
  96. northHeight, item->geometry().width(),
  97. item->geometry().height()));
  98. }
  99. }
  100. if (center)
  101. center->item->setGeometry(QRect(westWidth, northHeight,
  102. rect.width() - eastWidth - westWidth,
  103. centerHeight));
  104. }
  105. QSize QBorderLayout::sizeHint() const
  106. {
  107. return calculateSize(SizeHint);
  108. }
  109. QLayoutItem *QBorderLayout::takeAt(int index)
  110. {
  111. if (index >= 0 && index < list.size()) {
  112. ItemWrapper *layoutStruct = list.takeAt(index);
  113. return layoutStruct->item;
  114. }
  115. return 0;
  116. }
  117. void QBorderLayout::add(QLayoutItem *item, Position position)
  118. {
  119. list.append(new ItemWrapper(item, position));
  120. }
  121. QSize QBorderLayout::calculateSize(SizeType sizeType) const
  122. {
  123. QSize totalSize;
  124. for (int i = 0; i < list.size(); ++i) {
  125. ItemWrapper *wrapper = list.at(i);
  126. Position position = wrapper->position;
  127. QSize itemSize;
  128. if (sizeType == MinimumSize)
  129. itemSize = wrapper->item->minimumSize();
  130. else // (sizeType == SizeHint)
  131. itemSize = wrapper->item->sizeHint();
  132. if (position == North || position == South || position == Center)
  133. totalSize.rheight() += itemSize.height();
  134. if (position == West || position == East || position == Center)
  135. totalSize.rwidth() += itemSize.width();
  136. }
  137. return totalSize;
  138. }

使用

中央窗体使用QTextBrowser,四周以QLabel排列开来。

  1. QTextBrowser *pCentralWidget = new QTextBrowser(this);
  2. pCentralWidget->setPlainText(tr("Central Widget"));
  3. QBorderLayout *pLayout = new QBorderLayout();
  4. pLayout->addWidget(pCentralWidget, QBorderLayout::Center);
  5. pLayout->addWidget(createLabel("North"), QBorderLayout::North);
  6. pLayout->addWidget(createLabel("West"), QBorderLayout::West);
  7. pLayout->addWidget(createLabel("East 1"), QBorderLayout::East);
  8. pLayout->addWidget(createLabel("East 2") , QBorderLayout::East);
  9. pLayout->addWidget(createLabel("South"), QBorderLayout::South);
  10. setLayout(pLayout);
  11. QLabel *MainWindow::createLabel(const QString &text)
  12. {
  13. QLabel *pLabel = new QLabel(this);
  14. pLabel->setText(text);
  15. pLabel->setFrameStyle(QFrame::Box | QFrame::Raised);
  16. return pLabel;
  17. }

Qt之自定义布局管理器(QBorderLayout)的更多相关文章

  1. Qt之自定义布局管理器(QCardLayout)

    简述 手动布局另一种方法是通过继承QLayout类编写自己的布局管理器. 下面我们详细来举一个例子-QCardLayout.它由同名的Java布局管理器启发而来.也被称之为卡片布局,每个项目偏移QLa ...

  2. Qt之自定义布局管理器(QFlowLayout)

    简述 QFlowLayout,顾名思义-流布局,实现了处理不同窗口大小的布局.根据应用窗口的宽度来进行控件放置的变化. 具体实现要求不再赘述,请参考前两节内容. 简述 实现 效果 源码 实现 QFlo ...

  3. Qt中的布局管理器

    1. 布局管理器提供相关的类对界面组件进行布局管理,能够自动排列窗口中的界面组件,窗口变化后能自动更新界面组件的大小. 2. QLayout是Qt布局管理器的抽象基类,通过继承QLayout实现了功能 ...

  4. Qt之布局管理器

    简述 Qt的布局系统提供了一个简单的和强有力的方式,来自动排列窗口子控件布局. 所有QWidget子类可以使用布局来管理他们的子控件.QWidget::setLayout()函数可以为一个控件布局.当 ...

  5. Qt 布局管理器

    在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...

  6. QT5每日一学(五)QT布局管理器

    Qt中的布局管理器主要包括 QBoxLayout基本布局管理器 QGridLayout栅格布局管理器 QFormLayout窗体布局管理器 而基本布局管理器又分为QHBoxLayout水平布局管理器和 ...

  7. Java可视化编程,基于布局管理器的UI设计

    在<事件驱动模型>讲述了如何将用户与功能实现代码联系到一起.怎么样便于用户理解和符合用户的使用习惯? 本篇还是就此问题作分析,站在用户角度上分析UI各组件倒底该如何设计呈现. 优秀的UI会 ...

  8. 第六章 Qt布局管理器Layout

    第六章 Qt布局管理器Layout 大家有没有发现一个现象,我们放置一个组件,给组件最原始的定位是给出这个控件的坐标和宽高值,这样Qt就知道这个组件的位置.当用户改变窗口的大小,组件还静静地呆在原来的 ...

  9. Qt——布局管理器

    教程地址 运行截图: 代码: #include "mainwindow.h" #include <QApplication> #include <QHBoxLay ...

随机推荐

  1. NOI 2018 屠龙勇士 (拓展中国剩余定理excrt+拓展欧几里得exgcd)

    题目大意:略 真是一波三折的一道国赛题,先学了中国剩余定理,勉强看懂了模板然后写的这道题 把取出的宝剑攻击力设为T,可得Ti*x=ai(mod pi),这显然是ax=c(mod b)的形式 这部分用e ...

  2. BZOJ 3524 [POI2014]KUR-Couriers (主席树)

    题目大意:给你一个序列,求某个区间出现次数大于一半的数是什么 主席树裸题,刷刷水题提升自信= = #include <cstdio> #include <cstring> #i ...

  3. php的更新

    因为 PHP 那“集百家之长”的蛋疼语法,加上社区氛围不好,很多人对新版本,新特征并无兴趣.本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征 本文目录:PHP5.2 以前:auto ...

  4. 小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理)

    小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理) 异常处理(处理) 1.产生异常.raise 异常类(),抛出异常2. 处理异常: try: xxxxx # 尝试执行的代码. ...

  5. java开发必背API

    1.java.io.file类,File用于管理文件或目录: 所属套件:java.io File file = new File(fileStringPath); 1)file.mk(),真的会创建一 ...

  6. Linux网络编程(3)——多进程、多线程

    在我的里面已经介绍了linux以下c的进程.线程接口,这里就不做过多阐述了. 多进程 这里多进程採用传统的多进程模型.每当有client发来的连接时创建一个进程来处理连接,一个子进程相应一个连接. 有 ...

  7. 博客迁移到reetsee.com

    正如上一篇博客所言.眼下CSDN的博客已经基本完毕它的使命了.感谢CSDN带给我的全部美好回顾. 如今我想尝试一下自己维护一个博客,所以博客的全部内容都迁移到了reetsee.com. 以后博客更新会 ...

  8. webserver的作用!

    常见的webserver:Apache和Nginx(linux平台) IIS(window平台) 非常多小公司小项目眼下不一定使用了webserver,由于流量下,单台应用server能够支撑. 实际 ...

  9. PHP编译时错误解决:Don&#39;t know how to define struct flock on this system, set --enable-opcache=no

    在编辑PHP5.6.1时出现了这个错误: Don't know how to define struct flock on this system, set --enable-opcache=no 解 ...

  10. Android 的Recovery机制

    Android 的Recovery机制 文件夹 1. 系统的启动模式 1 1.1 Android系统的启动模式 1 1.2 系统的启动模式 2 2. Recovery模式中的三个部分 3 3. Rec ...