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个按钮来试试这新实现的卡片布局。看下效果:

相关推荐
fzb5QsS1p1 天前
告别重复造轮子,Qt 快速开发脚手架
开发语言·qt·php
森G1 天前
58、最佳实践与注意事项---------多线程、竟态条件和同步
c++·qt
小樱花的樱花1 天前
1 项目概述
开发语言·c++·qt·ui
MinterFusion1 天前
如何在openKylin 2.0 SP2中安装Qt(v0.2.2)(上)
开发语言·qt·软件开发·系统维护·明德融创·openkylin
特立独行的猫a1 天前
HarmonyOS鸿蒙PC的QT应用开发:(一、开发环境搭建及第一个HelloWorld)
qt·华为·harmonyos·鸿蒙pc
青花瓷1 天前
采用QT下MingW编译opencv4.8.1
开发语言·qt
cpp_learners1 天前
Linux ARM架构 使用 linuxdeployqt 打包QT程序
linux·arm开发·qt
森G1 天前
3.1、移植Qt程序到ARM平台----移植Qt程序到ARM平台(扩展)
arm开发·c++·qt
白杆杆红伞伞1 天前
Qt Event
开发语言·qt
Magic--1 天前
Qt 桌面计算器项目
开发语言·qt