简述

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

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

实现

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

效果

源码

QBorderLayout.h

#ifndef QBORDERLAYOUT_H
#define QBORDERLAYOUT_H #include <QLayout>
#include <QRect> class QBorderLayout : public QLayout
{
public:
enum Position {West, North, South, East, Center}; explicit QBorderLayout(QWidget *parent, int margin = 0, int spacing = -1);
QBorderLayout(int spacing = -1);
~QBorderLayout(); void addItem(QLayoutItem *item) Q_DECL_OVERRIDE;
void addWidget(QWidget *widget, Position position);
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
bool hasHeightForWidth() 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; void add(QLayoutItem *item, Position position); private:
struct ItemWrapper
{
ItemWrapper(QLayoutItem *i, Position p) {
item = i;
position = p;
} QLayoutItem *item;
Position position;
}; enum SizeType { MinimumSize, SizeHint };
QSize calculateSize(SizeType sizeType) const; QList<ItemWrapper *> list;
}; #endif // QBORDERLAYOUT_H

QBorderLayout.cpp

#include "QBorderLayout.h"

QBorderLayout::QBorderLayout(QWidget *parent, int margin, int spacing)
: QLayout(parent)
{
setMargin(margin);
setSpacing(spacing);
} QBorderLayout::QBorderLayout(int spacing)
{
setSpacing(spacing);
} QBorderLayout::~QBorderLayout()
{
QLayoutItem *l;
while ((l = takeAt(0)))
delete l;
} void QBorderLayout::addItem(QLayoutItem *item)
{
add(item, West);
} void QBorderLayout::addWidget(QWidget *widget, Position position)
{
add(new QWidgetItem(widget), position);
} Qt::Orientations QBorderLayout::expandingDirections() const
{
return Qt::Horizontal | Qt::Vertical;
} bool QBorderLayout::hasHeightForWidth() const
{
return false;
} int QBorderLayout::count() const
{
return list.size();
} QLayoutItem *QBorderLayout::itemAt(int index) const
{
ItemWrapper *wrapper = list.value(index);
if (wrapper)
return wrapper->item;
else
return 0;
} QSize QBorderLayout::minimumSize() const
{
return calculateSize(MinimumSize);
} void QBorderLayout::setGeometry(const QRect &rect)
{
ItemWrapper *center = 0;
int eastWidth = 0;
int westWidth = 0;
int northHeight = 0;
int southHeight = 0;
int centerHeight = 0;
int i; QLayout::setGeometry(rect); for (i = 0; i < list.size(); ++i) {
ItemWrapper *wrapper = list.at(i);
QLayoutItem *item = wrapper->item;
Position position = wrapper->position; if (position == North) {
item->setGeometry(QRect(rect.x(), northHeight, rect.width(),
item->sizeHint().height())); northHeight += item->geometry().height() + spacing();
} else if (position == South) {
item->setGeometry(QRect(item->geometry().x(),
item->geometry().y(), rect.width(),
item->sizeHint().height())); southHeight += item->geometry().height() + spacing(); item->setGeometry(QRect(rect.x(),
rect.y() + rect.height() - southHeight + spacing(),
item->geometry().width(),
item->geometry().height()));
} else if (position == Center) {
center = wrapper;
}
} centerHeight = rect.height() - northHeight - southHeight; for (i = 0; i < list.size(); ++i) {
ItemWrapper *wrapper = list.at(i);
QLayoutItem *item = wrapper->item;
Position position = wrapper->position; if (position == West) {
item->setGeometry(QRect(rect.x() + westWidth, northHeight,
item->sizeHint().width(), centerHeight)); westWidth += item->geometry().width() + spacing();
} else if (position == East) {
item->setGeometry(QRect(item->geometry().x(), item->geometry().y(),
item->sizeHint().width(), centerHeight)); eastWidth += item->geometry().width() + spacing(); item->setGeometry(QRect(
rect.x() + rect.width() - eastWidth + spacing(),
northHeight, item->geometry().width(),
item->geometry().height()));
}
} if (center)
center->item->setGeometry(QRect(westWidth, northHeight,
rect.width() - eastWidth - westWidth,
centerHeight));
} QSize QBorderLayout::sizeHint() const
{
return calculateSize(SizeHint);
} QLayoutItem *QBorderLayout::takeAt(int index)
{
if (index >= 0 && index < list.size()) {
ItemWrapper *layoutStruct = list.takeAt(index);
return layoutStruct->item;
}
return 0;
} void QBorderLayout::add(QLayoutItem *item, Position position)
{
list.append(new ItemWrapper(item, position));
} QSize QBorderLayout::calculateSize(SizeType sizeType) const
{
QSize totalSize; for (int i = 0; i < list.size(); ++i) {
ItemWrapper *wrapper = list.at(i);
Position position = wrapper->position;
QSize itemSize; if (sizeType == MinimumSize)
itemSize = wrapper->item->minimumSize();
else // (sizeType == SizeHint)
itemSize = wrapper->item->sizeHint(); if (position == North || position == South || position == Center)
totalSize.rheight() += itemSize.height(); if (position == West || position == East || position == Center)
totalSize.rwidth() += itemSize.width();
}
return totalSize;
}

使用

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

QTextBrowser *pCentralWidget = new QTextBrowser(this);
pCentralWidget->setPlainText(tr("Central Widget")); QBorderLayout *pLayout = new QBorderLayout();
pLayout->addWidget(pCentralWidget, QBorderLayout::Center);
pLayout->addWidget(createLabel("North"), QBorderLayout::North);
pLayout->addWidget(createLabel("West"), QBorderLayout::West);
pLayout->addWidget(createLabel("East 1"), QBorderLayout::East);
pLayout->addWidget(createLabel("East 2") , QBorderLayout::East);
pLayout->addWidget(createLabel("South"), QBorderLayout::South);
setLayout(pLayout); QLabel *MainWindow::createLabel(const QString &text)
{
QLabel *pLabel = new QLabel(this);
pLabel->setText(text);
pLabel->setFrameStyle(QFrame::Box | QFrame::Raised);
return pLabel;
}

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. [BZOJ1322]Destroying The Graph

    题目大意:有一张有向图,对于每个点,有两种操作:1. 删掉它的所有入边2. 删掉它的所有出边对每个点的每个操作均有不同的价值.求使得图上没有边的最小价值.解题思路:考虑把点拆成入点和出点,然后就是二分 ...

  2. [HDU1195]Open the Lock

    题目大意:给你一个4位数的初始状态(只包含1~9),要求你变化成另一个4位数. 变化规则为:每次可给任意一位加1或减1(1减1变为9,9加1变为1),或交换相邻两个数位上的数字(第一位和最后一位不相邻 ...

  3. ASP.NET--Attribute定义及用法

    1.Attribute定义 公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法和属性等.Attributes和Microsoft .N ...

  4. ASP.NET-Request对象

    前言:Request对象主要用于获取来自客户端的数据,如用户填入表单的数据.保存在客户端的Cookie等. 一.Request对象概述 1.主要属性  ApplicationPath  获取服务器上a ...

  5. oracle学习之第一个存储过程:打印Hello World

    数据库对象:表.视图.索引.序列.同义词.存储过程.存储函数 存储过程:指的是存储在数据库中供全部用户程序调用的子程序叫存储过程.存储函数 存储过程和存储函数的同样点:完毕特定功能的程序 存储过程和存 ...

  6. HDU 4331 Contest 4

    一个很直观的想法是,求出每个点上下左右能到达的最大长度.然后枚举其斜边...没想到过了.... 当然,题解有一个很巧妙的优化,利用树状数组,那个太巧妙了. #include<iostream&g ...

  7. Android内存优化之封装九宫格

    随着市场上越来越多的APP上线,好多软件对手机的内存要求也是很大,所以我们在开发的时候一定要掌握如何去优化内存,将自己的APP尽可能优化.今天我们就一起看一下九宫格的优化.下面是软件的截图 1.为了达 ...

  8. 【struts2】struts2中的流接收与流发送

    [前言]在我们的struts2后端中,实现流的接收和发送.就能够实现向server传视频流以及下载图片. [流接收] 如今举一个传公钥的样例.struts2用一个action接收Key,而Key就是用 ...

  9. ORA-01261: Parameter db_recovery_file_dest destination string cannot be translat

    查看了Oracle的初始化文件. $cat /oracle/oms/102_64/dbs/initSID.ora 如:db_recovery_file_dest='/oracle/oms/flash_ ...

  10. IDE-IntelliJ IDEA

    IDE-IntelliJ IDEA 主题.字体.编辑区主题.文件编码修改.乱码问题 主题修改 上图标注 1 所示为 IntelliJ IDEA 修改主题的地方,可以通过打开左上角的File -> ...