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

相关推荐
kaixin_learn_qt_ing7 小时前
Qt Model/View
qt
Quz8 小时前
QML MouseArea:鼠标拖拽与滚轮缩放
qt·qml
CHPCWWHSU10 小时前
DeepSeek-Harness-Qt将浏览器端Agent装入桌面应用
开发语言·qt
飘忽不定的bug14 小时前
ubuntu20.04交叉编译QT5.15.12(RK3562+ubuntu20.04)
linux·qt·ubuntu
秋田君17 小时前
Qt_QMediaPlayer类与QMediaPlaylist类
开发语言·qt
mengzhi啊17 小时前
QT程序界面自适应1080/2K/4K屏幕。qputenv或者setAttribute
qt
C++ 老炮儿的技术栈17 小时前
Qt5 使用 QPainter 绘制阿基米德螺线
开发语言·c++·windows·qt·代码化
大丑哥1 天前
QT QML 中实现高亮功能
qt
小白不想画工图2 天前
银河麒麟V10系统安装QT5.12
linux·开发语言·qt·银河麒麟
mengzhi啊2 天前
QEventLoop loop配合loop.exec();替代while(1)。电脑cpu占用为0,使用while(1)cpu占用率100%
c++·qt