当前位置:网站首页>QT notes - customized flow layout qflowlayout
QT notes - customized flow layout qflowlayout
2022-07-21 05:10:00 【Cool breeze in the old street °】
Want to achieve a streaming layout , as follows :
Just search online Related examples of flow layout
The code is as follows :
QFlowLayout.h
#pragma once
#include <QLayout>
#include <QStyle>
class QFlowLayout : public QLayout
{
Q_OBJECT
public:
explicit QFlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
explicit QFlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~QFlowLayout();
void addItem(QLayoutItem* item) Q_DECL_OVERRIDE;
int horizontalSpacing() const;
int verticalSpacing() const;
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
bool hasHeightForWidth() const Q_DECL_OVERRIDE;
int heightForWidth(int) const Q_DECL_OVERRIDE;
int count() const Q_DECL_OVERRIDE;
QLayoutItem* itemAt(int index) const Q_DECL_OVERRIDE;
QSize minimumSize() const Q_DECL_OVERRIDE;
void setGeometry(const QRect& rect) Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QLayoutItem* takeAt(int index) Q_DECL_OVERRIDE;
private:
int doLayout(const QRect& rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
private:
QList<QLayoutItem*> itemList; //layout Children of
int m_hSpace;
int m_vSpace;
};
QFlowLayout.cpp
#include <QWidget>
#include "QFlowLayout.h"
QFlowLayout::QFlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin); // Edge spacing
}
QFlowLayout::QFlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
QFlowLayout::~QFlowLayout()
{
QLayoutItem* item;
// All internal content is destructed
while ((item = takeAt(0)))
delete item;
}
void QFlowLayout::addItem(QLayoutItem* item)
{
itemList.append(item); // Add item to layout
}
int QFlowLayout::horizontalSpacing() const
{
// Spacing between widgets
if (m_hSpace >= 0) {
return m_hSpace;
}
else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); // Automatically and intelligently generate an interval when there is no interval
}
}
int QFlowLayout::verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
}
else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}
int QFlowLayout::count() const
{
return itemList.size(); // Returns the number of items in the layout
}
QLayoutItem* QFlowLayout::itemAt(int index) const
{
return itemList.value(index);
}
QLayoutItem* QFlowLayout::takeAt(int index)
{
if (index >= 0 && index < itemList.size())
return itemList.takeAt(index); // Delete and return to item , If an item is deleted , The remaining items will be renumbered .
return nullptr;
}
Qt::Orientations QFlowLayout::expandingDirections() const
{
return 0;
}
bool QFlowLayout::hasHeightForWidth() const
{
return true;
}
int QFlowLayout::heightForWidth(int width) const
{
int height = doLayout(QRect(0, 0, width, 0), true); // Widgets whose height depends on the width
return height;
}
void QFlowLayout::setGeometry(const QRect& rect)
{
// Calculate the geometry of the layout item
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize QFlowLayout::sizeHint() const
{
return minimumSize();
}
QSize QFlowLayout::minimumSize() const
{
QSize size;
for (const QLayoutItem* item : qAsConst(itemList))
size = size.expandedTo(item->minimumSize());
const QMargins margins = contentsMargins();
size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
return size;
}
int QFlowLayout::doLayout(const QRect& rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom); // Calculate the area available for the layout project
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
for (QLayoutItem* item : qAsConst(itemList)) {
const QWidget* wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX; // next item Of x coordinate
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
// At present item Of x The coordinates exceed the boundary
// Set to the first... Of the next line
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
return y + lineHeight - rect.y() + bottom;
}
int QFlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{
// When the father is QWidget=> The default spacing for the top-level layout is pm style .
// When the father is QLayout=> The default spacing of child layouts is determined by the spacing of the parent layout .
QObject* parent = this->parent();
if (!parent) {
return -1;
}
else if (parent->isWidgetType()) {
QWidget* pw = static_cast<QWidget*>(parent);
return pw->style()->pixelMetric(pm, nullptr, pw);
}
else {
return static_cast<QLayout*>(parent)->spacing();
}
}
QFlowLayoutTest.cpp
#include "QFlowLayoutTest.h"
QFlowLayoutTest::QFlowLayoutTest(QWidget* parent)
: QWidget(parent)
{
ui.setupUi(this);
flowLayout = new QFlowLayout(this,20,20,20);
for (int i = 0; i < 10; i++)
{
QPushButton* p = new QPushButton(QString::number(i));
p->setFixedSize(80, 40);
this->flowLayout->addWidget(p);
}
}
Reference blog :
Adjusted flow layout BUG
Fluid layout
边栏推荐
- What are the advantages of low code platforms over traditional IT development?
- C#使用合并的方法判断两个List是否相等,是否包含
- XMind中拷贝和复制的区别
- 【学习笔记】整除分块、线性筛、莫比乌斯反演
- kubernetes部署单节点Redis服务
- 【二叉树】重建二叉树(先序找根,中序分治)
- The direction of this
- Thirteen grammar learning of reflect
- A funnel chart, at a glance to find the growth grab! [attach a quick drawing tutorial, which is required for the first time]
- 【学习笔记】根号思维题
猜你喜欢
随机推荐
Two way LSTM Chinese microblog emotion classification project
Use Excel to make Gantt chart to track project progress (with drawing tutorial)
数论基础-
力扣 741. 摘樱桃
Hyperchain超块链史兴国接受36氪采访:客户合作咨询量都在翻倍
Can ev code signing certificates be self renewed?
Two dimensional convolution Chinese microblog emotion classification project
Force buckle 745 Prefix and suffix search
【学习笔记】AGC016
【翻译】读博士一年后对机器学习工程的思考
力扣 745. 前缀和后缀搜索
创建K26 SOM最小系统
02 requsets请求库
10 聊聊ThreadLocal
【JZOF-03】数组中重复的数字
Li Kou sword finger offer II 101 Divide equal sum subsets
[MySQL] temporary table & View
[learning notes] arc144
Leetcode力扣题解 - 30.串联所有单词的子串
【学习笔记】ARC144