CardLayout 实现自定义布局

自定义卡片布局CardLayout,这个布局是官方用来介绍怎么实现一个自定义布局的示例。

自定义布局第一步就是要继承QLayout 然而QLayout却是个抽象类,有几个纯虚函数必须要是实现下:

cpp 复制代码
virtual void addItem(QLayoutItem *item) = 0
//向布局中添加控件

virtual int count() const = 0
//布局中控件数量

virtual QLayoutItem *itemAt(int index) const = 0
//根据下标获取控件

virtual QLayoutItem *takeAt(int index) = 0
//根据下标移除控件

virtual QSize sizeHint() const = 0
//默认大小

这些还都只是对布局中子控件管理的功能,真正处理控件布局位置的函数却是:

cpp 复制代码
virtual void setGeometry(const QRect&) = 0

CardLayout 实现

接下来进入主题,看下这些函数都是怎么实现的,类定义:

cpp 复制代码
class CardLayout : public QLayout
 {
    Q_OBJECT
 public:
     CardLayout(QWidget *parent = nullptr);
     ~CardLayout();

     void addItem(QLayoutItem *item) override;
     int count() const override;
     QLayoutItem *itemAt(int) const override;
     QLayoutItem *takeAt(int) override;
     QSize sizeHint() const override;
     void setGeometry(const QRect &rect) override;

 private:
     QList<QLayoutItem*> list;
 };

对于子控件的管理用的是QList<QLayoutItem*>,简单直接。

成员函数实现:

cpp 复制代码
CardLayout::CardLayout(QWidget *parent):
    QLayout(parent)
{}
CardLayout::~CardLayout()
{
    QLayoutItem *item;
    while ((item = takeAt(0)))
        delete item;
}
void CardLayout::addItem(QLayoutItem *item)
{
    list.append(item);
}
int CardLayout::count() const
{
    return list.count();
}
QLayoutItem *CardLayout::itemAt(int idx) const
{
    return list.value(idx);
}
QLayoutItem *CardLayout::takeAt(int idx)
{
    return idx >= 0 && idx < list.size() ? list.takeAt(idx) : 0;
}
QSize CardLayout::sizeHint() const
{
    return QSize(0,0);
}
void CardLayout::setGeometry(const QRect &rect)
{
    QLayout::setGeometry(rect);
    if(list.size() == 0)
        return;

    int w = rect.width() - (list.count() - 1)*spacing();
    int h = rect.height() - (list.count() - 1)* spacing();
    int i = 0;
    while (i < list.size())
    {
        QLayoutItem *o = list.at(i);
        QRect geom(rect.x() + i*spacing(), rect.y() + i*spacing(), w, h);
        o->setGeometry(geom);
        ++i;
    }
}

sizeHint这里是直接给0,暂且也不需要它发挥作用。

看过setGeometry的实现后,这个自定义的卡片布局的就很清晰了,每个子控件就是向右下角依次做个偏移显示而已。

调用示例

cpp 复制代码
CardLayout * lay = new CardLayout;
for(int i=0; i<5; i++)
{
    lay->addItem(
        new QWidgetItem(new QPushButton(QString::number(i+1)))
        );
}
this->setLayout(lay);

弄了5个按钮来试试这新实现的卡片布局。看下效果:

相关推荐
bug和崩溃我都要2 小时前
QT 开发的专业截图录屏工具 - macOS版 / Windows版
windows·qt·mac·录屏·截屏
Python图像识别5 小时前
40-【2027毕设】YOLO11面部口罩检测识别系统 - Python完整源码+PyQt5界面+训练模型+数据集
python·qt·课程设计
Python图像识别5 小时前
39-【2027毕设】YOLO11行人摔倒检测系统 - Python完整源码+PyQt5界面+训练模型+数据集
python·qt·课程设计
Quz15 小时前
QML PathView:直线路径与曲线路径
qt·动画·qml
扶尔魔ocy16 小时前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行
qt·opengl·osg
西飘客1 天前
vs 怎么根据dll 生成lib文件
c++·qt
bkspiderx1 天前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
半杯咖啡半行码1 天前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
时间的拾荒人1 天前
Qt 界面优化:绘图详解 —— 从基础图形到图片处理
开发语言·qt·面试