简述

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. CRM系统 - 总结 (二) stark组件

    介绍: stark组件,是一个帮助开发者快速实现数据库表的增删改查+的组件.目标: 10s 中完成一张表的增删改查. 前戏: django项目启动时,自定义执行某个py文件. django启动时,且在 ...

  2. google浏览器安装接口测试工具postman方法

    Google安装postman: 未配好的文件下载(点击选择下面配好的直接用):下载 配置方法: 一:需要修改postman安装包中js/requester.js 和runner.js ,将其中的ai ...

  3. 小记如何有顺序的搭建一个Spring的web项目

    如何有顺序的搭建一个Spring的web项目 一.新建一个简单的maven,war工程 eclipse下如有报错,右键 Deployment 单击 Generate 生成web.xml后可解决报错 二 ...

  4. 一种神奇的双向循环链表C语言实现

    最近在看ucore操作系统的实验指导.里面提要一个双向循环链表的数据结构,挺有意思的. 其实这个数据结构本身并不复杂.在普通链表的基础上加一个前向指针,我们就得到了双向链表,再把头尾节点连起来就是双向 ...

  5. oracle查询表空间的位置

    SELECT * FROM Dba_Data_Files ddf WHERE ddf.tablespace_name = 'TablespaceName'; 以上SQL代码可以查询出表空间的所在路径和 ...

  6. lucene构建restful风格的简单搜索引擎服务

    来自于本人博客: lucene构建restful风格的简单搜索引擎服务 本人的博客如今也要改成使用lucene进行全文检索的功能,因此在这里把代码贴出来与大家分享 一,文件夹结构: 二,配置文件: 总 ...

  7. 中科燕园arcgis外包案例之12---供水供热管线GIS系统

    项目背景 绍兴县是浙江省第一个"数字城管"试点城市,也是全国第一个"数字城管"县级城市.随着经济的飞速发展.城市化步伐的加快,以及城市规模的扩大和现代化程度的不 ...

  8. HBase基本数据操作具体解释

    引言 本文档參考最新(截止2014年7月16日)的官方Ref Guide.Developer API编写. 全部代码均基于"hbase 0.96.2-hadoop2"版本号编写.均 ...

  9. 【BUG】android.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/toolbar_line.png from

    SafeGod在coolpad(4.0)上执行.登陆进去的设备列表界面遇到的问题.三星和索尼没有这个问题. 06-24 15:23:06.897: E/AndroidRuntime(12655): F ...

  10. bzoj3993: [SDOI2015]星际战争(网络流)

    3993: [SDOI2015]星际战争 题目:传送门 题解: 洛谷AC了,但是因为bzoj的spj有问题所以暂时没A 一道老题目了,二分时间然后网络流判断. 每次st-->武器连时间*攻击力 ...