Qt之自定义布局管理器(QFlowLayout)
简述
QFlowLayout,顾名思义-流布局,实现了处理不同窗口大小的布局。根据应用窗口的宽度来进行控件放置的变化。
具体实现要求不再赘述,请参考前两节内容。
实现
QFlowLayout主要采用QLayout和QWidgetItem实现,而窗口使用了QWidget和QPushButton。
效果
源码
QFlowLayout.h
#ifndef QFLOWLAYOUT_H
#define QFLOWLAYOUT_H
#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 *> itemList;
int m_hSpace;
int m_vSpace;
};
#endif // QFLOWLAYOUT_H
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);
}
QFlowLayout::QFlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing),
m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
QFlowLayout::~QFlowLayout()
{
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;
}
void QFlowLayout::addItem(QLayoutItem *item)
{
itemList.append(item);
}
int QFlowLayout::horizontalSpacing() const
{
if (m_hSpace >= 0) {
return m_hSpace;
} else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
}
int QFlowLayout::verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
} else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}
int QFlowLayout::count() const
{
return itemList.size();
}
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);
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, 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, 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();
}
}
Qt之自定义布局管理器(QFlowLayout)的更多相关文章
- Qt之自定义布局管理器(QCardLayout)
简述 手动布局另一种方法是通过继承QLayout类编写自己的布局管理器. 下面我们详细来举一个例子-QCardLayout.它由同名的Java布局管理器启发而来.也被称之为卡片布局,每个项目偏移QLa ...
- Qt之自定义布局管理器(QBorderLayout)
简述 QBorderLayout,顾名思义-边框布局,实现了排列子控件包围中央区域的布局. 具体实现要求不再赘述,请参考前几节内容. 简述 实现 效果 源码 使用 实现 QBorderLayout主要 ...
- Qt中的布局管理器
1. 布局管理器提供相关的类对界面组件进行布局管理,能够自动排列窗口中的界面组件,窗口变化后能自动更新界面组件的大小. 2. QLayout是Qt布局管理器的抽象基类,通过继承QLayout实现了功能 ...
- Qt之布局管理器
简述 Qt的布局系统提供了一个简单的和强有力的方式,来自动排列窗口子控件布局. 所有QWidget子类可以使用布局来管理他们的子控件.QWidget::setLayout()函数可以为一个控件布局.当 ...
- Qt 布局管理器
在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...
- QT5每日一学(五)QT布局管理器
Qt中的布局管理器主要包括 QBoxLayout基本布局管理器 QGridLayout栅格布局管理器 QFormLayout窗体布局管理器 而基本布局管理器又分为QHBoxLayout水平布局管理器和 ...
- Java可视化编程,基于布局管理器的UI设计
在<事件驱动模型>讲述了如何将用户与功能实现代码联系到一起.怎么样便于用户理解和符合用户的使用习惯? 本篇还是就此问题作分析,站在用户角度上分析UI各组件倒底该如何设计呈现. 优秀的UI会 ...
- 第六章 Qt布局管理器Layout
第六章 Qt布局管理器Layout 大家有没有发现一个现象,我们放置一个组件,给组件最原始的定位是给出这个控件的坐标和宽高值,这样Qt就知道这个组件的位置.当用户改变窗口的大小,组件还静静地呆在原来的 ...
- Qt——布局管理器
教程地址 运行截图: 代码: #include "mainwindow.h" #include <QApplication> #include <QHBoxLay ...
随机推荐
- poj 3420 Quad Tiling (状压dp+多米诺骨牌问题+矩阵快速幂)
还有这种操作?????? 直接用pre到now转移的方式构造一个矩阵就好了. 二进制长度为m,就构造一个长度为1 << m的矩阵 最后输出ans[(1 << m) - 1][( ...
- Unity 多场景打包
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50580641 作者:car ...
- 常用js方法封装
常用js方法封装 var myJs = { /* * 格式化日期 * @param dt 日期对象 * @returns {string} 返回值是格式化的字符串日期 */ getDates: fun ...
- Docker学习总结(13)——从零开始搭建Jenkins+Docker自动化集成环境
本文只简单标记下大概的步骤,具体搭建各个部分的细节,还请自行搜索.第一.二部分只是对Jenkins和Docker的简单介绍,熟悉的同学请直接跳到第三部分. 一.关于Jenkins Jenkins简介 ...
- 今天开始看看brpc-baidurpc
链接如下: Link 大概看了一下.没有很明显的感觉.还是喜欢机器学习相关的内容.
- 海尔公布首套智能套装SmartCare,主打智能、简单
2014CIE智能硬件首发会于11月6-8日在上海国际展览中心举行.吸引了海尔.英特尔.百度等知名企业的积极參与. 作为国内智能家居领域的先驱者,海尔在本次大会上首发了轻量智能套装SmartC ...
- Sublime Text 3 添加到右键菜单
Sublime Text 3 添加到右键菜单 学习了:http://jingyan.baidu.com/article/cdddd41c99d07653ca00e147.html Windows Re ...
- 《UNIX环境高级编程》读书笔记之系统数据文件和信息(1)
1.UNIX系统口令文件包括了下图所看到的的各字段,这些字段包括在<pwd.h>中定义的passwd结构体中 POSIX定义了两个获取口令文件项的函数. 在给出用户登录名或用户ID后.这两 ...
- java-集合类(二)
使用场景 1.多线程 (1)在jdk1.5之前原始的集合类中,仅仅有vector.stack.hashtable.enumeration等是线程安全的,其它的都是非线程安全的. 非线程安全的集合在多线 ...
- node--20 moogose demo2
db.js /** * Created by Danny on 2015/9/28 16:44. */ //引包 var mongoose = require('mongoose'); //创建数据库 ...