• 10840阅读
  • 12回复

FlowLayout,从Qt Demo&Examples里提取出来的 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2012-07-15
关键词: FlowLayout
从左向右自动布局,自动换行,这个很有用。

文件FlowLayout.hpp
  1. #ifndef FLOWLAYOUT_HPP
  2. #define FLOWLAYOUT_HPP
  3. #include <QtCore>
  4. #include <QtGui>
  5. class FlowLayout : public QLayout
  6. {
  7. public:
  8.     FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1,
  9.             int vSpacing = -1);
  10.     FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
  11.     ~FlowLayout();
  12.     
  13.     void addItem(QLayoutItem *item);
  14.     int horizontalSpacing() const;
  15.     int verticalSpacing() const;
  16.     Qt::Orientations expandingDirections() const;
  17.     bool hasHeightForWidth() const;
  18.     int heightForWidth(int) const;
  19.     int count() const;
  20.     QLayoutItem *itemAt(int index) const;
  21.     QSize minimumSize() const;
  22.     void setGeometry(const QRect &rect);
  23.     QSize sizeHint() const;
  24.     QLayoutItem *takeAt(int index);
  25. private:
  26.     int doLayout(const QRect &rect, bool testOnly) const;
  27.     int smartSpacing(QStyle::PixelMetric pm) const;
  28.     
  29.     QList<QLayoutItem *> itemList;
  30.     int m_hSpace;
  31.     int m_vSpace;
  32. };
  33. #endif


CPP文件FlowLayout.cpp
  1. #include <QtGui>
  2. #include "FlowLayout.hpp"
  3. FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing,
  4.         int vSpacing)
  5.     : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
  6. {
  7.     setContentsMargins(margin, margin, margin, margin);
  8. }
  9. FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
  10.     :m_hSpace(hSpacing), m_vSpace(vSpacing)
  11. {
  12.     setContentsMargins(margin, margin, margin, margin);
  13. }
  14. FlowLayout::~FlowLayout()
  15. {
  16.     QLayoutItem *item;
  17.     while ((item = takeAt(0)))
  18.         delete item;
  19. }
  20. void FlowLayout::addItem(QLayoutItem *item)
  21. {
  22.     itemList.append(item);
  23. }
  24. int FlowLayout::horizontalSpacing() const
  25. {
  26.     if (m_hSpace >= 0)
  27.     {
  28.         return m_hSpace;
  29.     }
  30.     else
  31.     {
  32.         return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
  33.     }
  34. }
  35. int FlowLayout::verticalSpacing() const
  36. {
  37.     if (m_vSpace >= 0)
  38.     {
  39.         return m_vSpace;
  40.     }
  41.     else
  42.     {
  43.         return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
  44.     }
  45. }
  46. int FlowLayout::count() const
  47. {
  48.     return itemList.size();
  49. }
  50. QLayoutItem *FlowLayout::itemAt(int index) const
  51. {
  52.     return itemList.value(index);
  53. }
  54. QLayoutItem *FlowLayout::takeAt(int index)
  55. {
  56.     if (index >= 0 && index < itemList.size())
  57.         return itemList.takeAt(index);
  58.     else
  59.         return 0;
  60. }
  61. Qt::Orientations FlowLayout::expandingDirections() const
  62. {
  63.     return 0;
  64. }
  65. bool FlowLayout::hasHeightForWidth() const
  66. {
  67.     return true;
  68. }
  69. int FlowLayout::heightForWidth(int width) const
  70. {
  71.     int height = doLayout(QRect(0, 0, width, 0), true);
  72.     return height;
  73. }
  74. void FlowLayout::setGeometry(const QRect &rect)
  75. {
  76.     QLayout::setGeometry(rect);
  77.     doLayout(rect, false);
  78. }
  79. QSize FlowLayout::sizeHint() const
  80. {
  81.     return minimumSize();
  82. }
  83. QSize FlowLayout::minimumSize() const
  84. {
  85.     QSize size;
  86.     QLayoutItem *item;
  87.     foreach (item, itemList)
  88.         size = size.expandedTo(item->minimumSize());
  89.     size += QSize(2*margin(), 2*margin());
  90.     return size;
  91. }
  92. int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
  93. {
  94.     int left, top, right, bottom;
  95.     getContentsMargins(&left, &top, &right, &bottom);
  96.     QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
  97.     int x = effectiveRect.x();
  98.     int y = effectiveRect.y();
  99.     int lineHeight = 0;
  100.     QLayoutItem *item;
  101.     foreach (item, itemList)
  102.     {
  103.         QWidget *wid = item->widget();
  104.         int spaceX = horizontalSpacing();
  105.         if (spaceX == -1)
  106.             spaceX = wid->style()->layoutSpacing(
  107.                     QSizePolicy::PushButton, QSizePolicy::PushButton,
  108.                     Qt::Horizontal);
  109.         int spaceY = verticalSpacing();
  110.         if (spaceY == -1)
  111.             spaceY = wid->style()->layoutSpacing(
  112.                     QSizePolicy::PushButton, QSizePolicy::PushButton,
  113.                     Qt::Vertical);
  114.         int nextX = x + item->sizeHint().width() + spaceX;
  115.         if (nextX - spaceX > effectiveRect.right() && lineHeight > 0)
  116.         {
  117.             x = effectiveRect.x();
  118.             y = y + lineHeight + spaceY;
  119.             nextX = x + item->sizeHint().width() + spaceX;
  120.             lineHeight = 0;
  121.         }
  122.         if (!testOnly)
  123.             item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
  124.         x = nextX;
  125.         lineHeight = qMax(lineHeight, item->sizeHint().height());
  126.     }
  127.     return y + lineHeight - rect.y() + bottom;
  128. }
  129. int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
  130. {
  131.     QObject *parent = this->parent();
  132.     if (!parent)
  133.     {
  134.         return -1;
  135.     }
  136.     else if (parent->isWidgetType())
  137.     {
  138.         QWidget *pw = static_cast<QWidget *>(parent);
  139.         return pw->style()->pixelMetric(pm, 0, pw);
  140.     }
  141.     else
  142.     {
  143.         return static_cast<QLayout *>(parent)->spacing();
  144.     }
  145. }
下面这个图是程序在960x600分辨率下自FlowLayout自适应每行显示4个产品的截图


下面这个图是程序在1280x800分辨率下FlowLayout自适应每行显示5个产品的截图

二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线kimtaikee

只看该作者 1楼 发表于: 2012-07-16
如果配图的话就更有说服力了

离线gongkongrs

只看该作者 2楼 发表于: 2012-07-18
离线lyjbbq

只看该作者 3楼 发表于: 2012-08-17
mark
离线liuxu_lx7
只看该作者 4楼 发表于: 2012-11-24
离线phpqinsir
只看该作者 5楼 发表于: 2012-12-12
Qt好像没有类似于Java的那种流式布局吧。这个是您写的么?
qtcn.org是我见过最热心的论坛,也是解决问题率最高的论坛。希望,我的问题能让更多的人少走弯路。
离线XChinux

只看该作者 6楼 发表于: 2012-12-12
引用第5楼phpqinsir于2012-12-12 11:54发表的  :
Qt好像没有类似于Java的那种流式布局吧。这个是您写的么?

Qt自带的Demo and Examples里的,我将它提取了出来。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线wujianhui

只看该作者 7楼 发表于: 2012-12-27
学习QLayout,真是好东西
离线kimtaikee

只看该作者 8楼 发表于: 2013-01-23
使用ing

离线daily66

只看该作者 9楼 发表于: 2013-01-25
谢谢偻主分享,我先收下了。
在此还请高人去帮助我解决一下我遇到的一个Qt的Bug,链接如下,先谢过了
http://www.qtcn.org/bbs/read-htm-tid-52583.html
离线xzoscar
只看该作者 10楼 发表于: 2013-02-04
XZoscar@163.com
QQ,351565950
南京
离线zxh1982a

只看该作者 11楼 发表于: 2013-02-26
请问一下版主,怎么样可以将你这个FlowLayout生成一个Qt设计师控件,可以像QVBoxLayout这些一样?
离线XChinux

只看该作者 12楼 发表于: 2013-02-26
引用第11楼zxh1982a于2013-02-26 14:11发表的  :
请问一下版主,怎么样可以将你这个FlowLayout生成一个Qt设计师控件,可以像QVBoxLayout这些一样?



我也没搞过,所以暂时只能看谁搞过这方面的东西了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个