Qt之流式布局QFlow

Qt之流式布局QFlow

2018年11月14日 14:18:09 忆秋年jd 阅读数 690更多

分类专栏: Qt C++

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.youkuaiyun.com/w18758879921/article/details/84065788

 

文章目录


Qt没有像网页那种能根据窗口大小改变的布局,但是我们可以利用继承QLayout 自己编写

 

环境

Qt5.6.2+VS2013

代码

FlowLayout.h

#ifndef FLOWLAYOUT_H
#define FLOWLAYOUT_H

#include <QLayout>
#include <QRect>
#include <QStyle>

#include <QLayout>
#include <QRect>
#include <QStyle>

class QFlowLayout : public QLayout
{
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 *> x_itemList;
	int x_hSpace;
	int x_vSpace;
};
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

FlowLayout.cpp

#include "FlowLayout.h"

#include <algorithm>
#include <QWidget>

QFlowLayout::QFlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
	: QLayout(parent),
	x_hSpace(hSpacing),
	x_vSpace(vSpacing)
{
	setContentsMargins(margin, margin, margin, margin);
}

QFlowLayout::QFlowLayout(int margin, int hSpacing, int vSpacing)
	: x_hSpace(hSpacing),
	x_vSpace(vSpacing)
{
	setContentsMargins(margin, margin, margin, margin);
}

QFlowLayout::~QFlowLayout()
{
	QLayoutItem *item;
	while ((item = takeAt(0)))
		delete item;
}

void QFlowLayout::addItem(QLayoutItem *item)
{
	x_itemList.append(item);
}

int QFlowLayout::horizontalSpacing() const
{
	if (x_hSpace >= 0) 
	{
		return x_hSpace;
	}
	else 
	{
		return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
	}
}

int QFlowLayout::verticalSpacing() const
{
	if (x_vSpace >= 0) {
		return x_vSpace;
	}
	else {
		return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
	}
}

int QFlowLayout::count() const
{
	return x_itemList.size();
}

QLayoutItem *QFlowLayout::itemAt(int index) const
{
	return x_itemList.value(index);
}

QLayoutItem *QFlowLayout::takeAt(int index)
{
	if (index >= 0 && index < x_itemList.size())
		return x_itemList.takeAt(index);
	else
		return 0;
}

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);
	return height;
}

void QFlowLayout::setGeometry(const QRect &rect)
{
	QLayout::setGeometry(rect);
	doLayout(rect, false);
}

QSize QFlowLayout::sizeHint() const
{
	return minimumSize();
}

QSize QFlowLayout::minimumSize() const
{
	QSize size;
	QLayoutItem *item;
	foreach(item, x_itemList)
		size = size.expandedTo(item->minimumSize());

	size += QSize(2 * margin(), 2 * margin());
	return size;
}

int QFlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
	int left, top, right, bottom;
	getContentsMargins(&left, &top, &right, &bottom);
	QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
	int x = effectiveRect.x();
	int y = effectiveRect.y();
	int lineHeight = 0;

	QLayoutItem *item;
	foreach(item, x_itemList) {
		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;
		if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
			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
{
	QObject *parent = this->parent();
	if (!parent) {
		return -1;
	}
	else if (parent->isWidgetType()) {
		QWidget *pw = static_cast<QWidget *>(parent);
		return pw->style()->pixelMetric(pm, 0, pw);
	}
	else {
		return static_cast<QLayout *>(parent)->spacing();
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162

使用

#include "FlowLayout.h"

QFlowLayout* _pFlowLayout = new QFlowFlayout();

_pFlowLayout FlowLayout->addWidget(new QPushButton("1"));
_pFlowLayout ->addWidget(new QPushButton("2"));
_pFlowLayout ->addWidget(new QPushButton("3"));
_pFlowLayout ->addWidget(new QPushButton("4444444444444444"));
_pFlowLayout ->addWidget(new QPushButton("55"));
_pFlowLayout ->addWidget(new QPushButton("6"));

setLayout(x_pFlowLayout);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

效果在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值