简述

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. CF833B The Bakery (线段树+DP)

    题目大意:给你一个序列(n<=35000),最多分不大于m块(m<=50),求每个块内不同元素的数量之和的最大值 考试的时候第一眼建图,没建出来,第二眼贪心 ,被自己hack掉了,又随手写 ...

  2. freeswitch GUI界面(portal)

    1.控制台 加载模块 load mod_xml_rpc 2.ip:8080/portal 进行登录  账号 : freeswitch  密码 : works 让模块随着freeswitch启动进行加载 ...

  3. 七、利用frp 穿透到内网的http/https网站,实现对外开放

    有域名的话使用域名,没有域名的话使用IP注意80端口是否被已经安装使用的nginx占用,若被占用,可以换成其他端口,比如8080,,或者利用nginx的反向代理实现frp服务端与nginx共用80端口 ...

  4. [LeetCode] 860. 柠檬水找零 lemonade-change(贪心算法)

    思路: 收到5块时,只是添加:收到十块时,添加10块,删除一个5块:收到20块时,添加20,删除一个10块一个5块,或者直接删除3个5块(注意:这里先删除5+10优于3个5) class Soluti ...

  5. idea 编辑器 光标问题!(insert键)

    今天写代码不小心按了键盘的insert键,光标莫名闪退了 ,重新打开的时候发现 光标变成了  按了insert 的效果  ,简直无语的要命啊! 这敲代码太恶心了!怒搜资料 结果找到了解决办法! 1.打 ...

  6. LoadRunner监控Window/Unix系统资源的配置

    LoadRunner监控Window/Unix系统资源需要做两件事情: 1.配置被监视的服务器,以便于LoadRunner能够获取系统资源使用情况的数据 2.在LoadRunner的Controlle ...

  7. java源码之HashMap和HashTable的异同

    代码版本 JDK每一版本都在改进.本文讨论的HashMap和HashTable基于JDK 1.7.0_67 1. 时间 HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2.从 ...

  8. Docker可视化管理工具对比(DockerUI、Shipyard、Rancher、Portainer)

    1.前言 谈及docker,避免不了需要熟练的记住好多命令及其用法,对于熟悉shell.技术开发人员而言,还是可以接受的,熟练之后,命令行毕竟是很方便的,便于操作及脚本化.但对于命令行过敏.非技术人员 ...

  9. Java类载入器

    1.   系统载入器简单介绍 Java虚拟机中能够安装多个类载入器,系统默认三个主要类载入器(BootStrap.ExtClassLoader.AppClassLoader).每一个类载入器负责载入特 ...

  10. linux数据库升级

    转自:老左博客:http://www.laozuo.org/6145.html 老左今天有在帮朋友的博客搬迁到另外一台VPS主机环境,其环境采用的是LLSMP架构的,原先的服务器采用的是LNMP网站环 ...