Qt之自定义布局管理器(QBorderLayout)

2023-11-20

简述

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

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

  • 简述
  • 实现效果源码
  • 使用

实现

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

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

效果

源码

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开发学习资料包、技术视频,内容包括(Qt实战项目,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt之自定义布局管理器(QBorderLayout) 的相关文章

  • 调整 QML 图像显示尺寸

    我有一个带有嵌套的 QML 窗口RowLayout 在内排我有两个图像 来源 png这些图像的文件 故意 相当大 当我尝试设置height这些图像上的属性使它们变小 但它们仍然被画得很大 Desired Appearance Actual
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • 从 QML 实例化 C++ 对象会产生巨大的内存使用开销

    实例化一个QObjectC 堆中的派生类为每个对象提供了大约 160 个字节 通过注册相同的对象qmlRegisterType 用于从 QML 创建并通过以下方式动态创建对象createObject 每个对象给我 2000 多个字节 这是完
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 使用 cmake 将两种解决方案合二为一

    我有两个单独的 Visual Studio 2013 解决方案 我想将它们迁移到一个解决方案中 因为第一个解决方案 使用 Qt 充当第二个解决方案的 GUI 最后 我希望有一个结构如下的单一解决方案 Solution All Build P
  • 如何创建QWidget的屏幕截图?

    我在 Qt Creator 中做作业 在其中绘制 QWidget 并且需要保存此 QWdiget 的某些部分 我试图解决这个问题 QPixmap pixmap pixmap copy rectangle rectangle is part
  • (如何)我可以抑制未找到包配置文件的警告吗?

    我正在尝试创建一个CMakeLists txt尝试查找的文件Qt5 如果失败 则尝试回退到Qt4安装 该脚本到目前为止有效 但如果出现以下情况我总会收到警告Qt5未安装 注意FindQt5 cmake是由提供Qt5并且仅当以下情况时才可用Q
  • Qt中如何获取鼠标在屏幕上的位置?

    我想获取屏幕上的鼠标坐标 我怎样才能在 Qt 中做到这一点 在 Windows 上 使用 C 我正在做类似答案中建议的事情对于这个问题 https stackoverflow com q 11737665 1420197 正如文档所述 QC
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • QGraphicsScene::clear 不会改变 sceneRect

    我有一个 QGraphicsScene 场景 和 QGraphicsView graphicsView 我有一个画图的方法 当我需要重绘所有图形时 我调用这个方法 一切都好 但我意识到 scene gt clear 不会改变 sceneRe
  • 使用 Visual Studio 2013 构建 Qt 5.2.1 的静态版本

    几天来我一直在尝试使用 Visual Studio 2013 构建 Qt 的静态版本 我就是不明白我做错了什么 System Windows 7 64 位 Visual Studio 2013 仍安装 Visual Studio 2012
  • 为 Windows 98 编译 Qt

    我需要支持 Windows 98 Qt 文档声称这是可能的 但没有说明 Qt 4 6 的分布式二进制文件不能在 Win98 上运行 而且我采样的大多数 Qt 应用程序也不能在 Win98 上运行 对于几个确实在 98 上运行的应用程序 我询
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 退出 Qt 程序的正确方法?

    我应该如何退出 Qt 程序 例如在加载数据文件时 发现文件损坏 并且用户需要退出该应用程序或重新启动数据文件 我是不是该 call exit EXIT FAILURE call QApplication quit call QCoreApp
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • PyQt5:如何使QThread返回数据到主线程

    I am a PyQt 5 4 1 1初学者 我的Python是3 4 3 这是我尝试遵循的many https mayaposch wordpress com 2011 11 01 how to really truly use qthr
  • Qt 插槽是否与其他代码并行运行?

    在此函数示例中 void MyClass myFunction emit MySignal1 emit MySignal2 如果我有slot1倾听MySignal1 and slot2倾听MySignal2 1 Is slot1总是会在之前
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • Qt 是否已经有了自己的 new 和 delete 运算符?

    我正在使用一个QGraphicsScene小部件并在其上显示一些点QGraphicsRectItem 这意味着要拨打很多电话new addItem 当出现时 并且removeItem delete摆脱未使用的点 当然 对于性能问题 我已经实
  • QML 连接:不推荐使用连接中隐式定义的 onFoo 属性

    升级到 Qt 5 15 时收到以下错误消息 QML Connections Implicitly defined onFoo properties in Connections are deprecated Use this syntax

随机推荐

  • Alpha多样性之箱线图绘制

    Alpha多样性 通常用Richness Chao1 Shannon Simpson Dominance和Equitability等指数来评估样本的物种多样性 所以这个节学习主要分两个部分 1 计算 生物多样性指数 软件 R软件中vegan
  • 副业是刚需?分享几个程序员接外包私活的网站

    经常看到某某程序员接了个项目开发 工作之余轻轻松松赚了钱还顺带提升了技术 或者看到某大佬又发表了一篇程序员技术提升稿件 阅读点赞收藏三连发 这个月的零花钱又不愁了 但自己只是一名普普通通的程序员 能找到这样的副业吗 这些项目又在哪里接的呢
  • 网站为什么建议用https协议

    HTTPS 全称 Hyper Text Transfer Protocol over SecureSocket Layer 是以安全为目标的 HTTP 通道 在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 HTTPS 在HT
  • STM32f103增加ESP8266模块,通过Wifi用手机TCP服务端远程与STM32通信

    STM32f103增加ESP8266模块 通过Wifi用手机TCP服务端远程与STM32通信 提示 esp8266开启透传模式 连上路由器Wifi 电脑热点 接入STM32串口引脚 另外手机TCP服务端是手机IP地址 串口号 大于8000滴
  • 仅需三步就可以把代码块完美插入到word中

    还在为在word中呈现代码而烦恼吗 如何在word中插入c 代码 如何在word中插入代码块 如何在word中完美的呈现代码 如何在word中对代码进行排版 来开始表演了 1 打开网站 http word wd1x com 支持c c ja
  • keil提示找不到芯片库

    keil提示找不到芯片库 有几种可能 一种是没安装芯片软件包 下载相应芯片包即可 还有一种可能是工程本身是用keil4创建的 而你用的是keil5打开的 此种情况将后缀名uvproj改成uvprojx即可 图1
  • java获取method_从Method中获取完整类名和方法名

    需求假设 假设在包com zhoutao controller下有方法getKey 方法 在JavaEE中 通过AOP获得该方法的的对象method 现在通过该对象的getName方法 仅仅只能获得getKey的结果 现在我需要的是com
  • 性别年龄识别器

    心情 最近比较郁闷 自己的小论文已经投了快8个月了 从去年的AAAI CVPR 到现在在审的TCSVT AAAI由于页数超限被拒 CVPR因为一个正面和2个负面评价被拒 TCSVT还前途未卜 真的很郁闷 心情不好 论文也不太想看 撸撸代码放
  • Idea快速开发SpringBoot项目的方法

    一 常用插件 1 Free Mybatis plugins 针对Mybatis框架提供的插件 自动完成Mapper接口和Mapper xml之间的跳转 2 RestfulTool 自动显示工程中的所有URL接口 进行测试 并且提供检索功能
  • Elasticsearch(十三) ElasticSearch搜索附近的人

    需求 通过指定点搜索附近的人 要求可以过滤年龄 结果按照距离进行排序 并且展示她 他距离你多远 本文参考 es官网文档 https www elastic co guide cn elasticsearch guide current so
  • 面试题:StringBuilder 和 StringBuffer 区别(通俗易懂易背)

    StringBuffer是同步的 线程安全 StringBuilder不是 什么时候用哪一个 StringBuilder 当您需要一个可以修改的字符串 并且只有一个线程正在访问和修改它时 StringBuffer 当你需要一个可以修改的字符
  • sql: Compare Tables

    使用 UNION INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式 select from BookInfoList 存在不同的 select BookInfoID BookInfoBarCod
  • VMware安装OpenEuler

    VMware安装OpenEuler 需要考虑的因素 安装系统的用途 桌面开发 服务器 Linux学习使用 磁盘分区规划 最小120G 划分 boot swap 根分区等 网络 是否对外提供服务 NAT模式 桥接模式 仅主机模式 1 下载镜像
  • 前端大屏常用的适配方案

    假设我们正在开发一个可视化拖拽的搭建平台 可以拖拽生成工作台或可视化大屏 或者直接就是开发一个大屏 首先必须要考虑的一个问题就是页面如何适应屏幕 因为我们在搭建或开发时一般都会基于一个固定的宽高 但是实际的屏幕可能大小不一 接下来我们就尝试
  • 安卓10开机时间优化分析

    本文从以下六点分析开机时间 1 软件环境 2 开机时间测试方法 3 开机各阶段重要的时间节点 4 bootchart工具使用说明 5 Android开机时间日志信息 6 开机时间优化方案 一 软件环境 平台 android10 0 qcom
  • Stem教育是探究式的学习方式

    在国家政策的扶持下 STEM教育慢慢进入大众的视野 走近一部分大中小学生的课堂 教育部出台的 教育信息化 十三五 规划 中明确指出有效利用信息技术推进 众创空间 建设 探索STEM教育 创客教育等新教育模式 使学生具有较强的信息意识与创新意
  • virtualbox 3.0.8 下载

    http download virtualbox org virtualbox 3 0 8
  • java命令执行jar包main方法指定相关依赖

    1 准备好工程执行所需的所有依赖jar包 也可以使用maven导出依赖的方法导出 2 将工程打包 此处打成jar包 如上图所示 zookeeper learn 1 0 SNAPSHOT jar 本次需要jdk java命令执行的jar包 3
  • #互联网生活中的隐私保护:用隐私换便利还是花钱护隐私?# 隐私保护与个人信息安全:在便利与隐私之间的取舍

    文章目录 1 看法 2 互联网生存指南 通过哪些方法来加强个人信息保护 2 1 加强个人信息安全意识 2 2 使用强密码和多因素认证 2 3 更新操作系统和软件 2 4 谨慎使用公共Wi Fi网络 2 5 定期备份个人数据 2 6 注意社交
  • Qt之自定义布局管理器(QBorderLayout)

    简述 QBorderLayout 顾名思义 边框布局 实现了排列子控件包围中央区域的布局 具体实现要求不再赘述 请参考前几节内容 简述 实现效果源码 使用 实现 QBorderLayout主要采用QLayout和QWidgetItem实现