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

简述

手动布局另一种方法是通过继承QLayout类编写自己的布局管理器。

下面我们详细来举一个例子-QCardLayout。它由同名的Java布局管理器启发而来。也被称之为卡片布局,每个项目偏移QLayout::spacing()。

  • 简述
  • 定义
  • 实现
    • 效果
    • 源码

定义

编写自己的布局,必须定义如下:

  • 一种存储布局处理项目的数据结构,每个项目都是一个QLayoutItem,本例使用QList。

  • addItem() 如何添加项目布局。

  • setGeometry() 如何控制布局。

  • sizeHint() 布局的优选大小。

  • itemAt() 如何遍历布局。

  • takeAt() 如何删除布局中的项目。

大多数情况下,也会实现的minimumSize()。

实现

效果

源码

QCardLayoud.h

#ifndef QCARDLAYOUT_H
#define QCARDLAYOUT_H

#include <QWidget>
#include <QLayout>
#include <QLayoutItem>

class QCardLayout : public QLayout {
public:
    QCardLayout(QWidget *parent = 0);
    ~QCardLayout();
    void addItem(QLayoutItem *item);
    QSize sizeHint() const;
    QSize minimumSize() const;
    int count() const;
    QLayoutItem *itemAt(int) const;
    QLayoutItem *takeAt(int);
    void setGeometry(const QRect &rect);

private:
    QList<QLayoutItem*> list;
};

#endif //QCARDLAYOUT_H

QCardLayoud.cpp

#include "QCardLayout.h"

QCardLayout::QCardLayout(QWidget *parent)
    : QLayout(parent)
{

}

// 由于QLayoutItem不继承自QObject,必须手动删除。在析构函数中,使用takeAt()删除列表中的每个项目,然后将其删除。
QCardLayout::~QCardLayout()
{
    QLayoutItem *item;
    while ((item = takeAt(0)))
        delete item;
}

// 获取列表中的项目数
int QCardLayout::count() const
{
    return list.size();
}

// 获取索引idx所对应的项目
QLayoutItem *QCardLayout::itemAt(int idx) const
{
    return list.value(idx);
}

// 移除索引idx所对应的项目,并返回
QLayoutItem *QCardLayout::takeAt(int idx)
{
    return idx >= 0 && idx < list.size() ? list.takeAt(idx) : 0;
}

// 添加项目
void QCardLayout::addItem(QLayoutItem *item)
{
    list.append(item);
}

// 实际控制着布局,作为参数提供的矩形不包括margin()。相关的,使用spacing()作为项目之间的距离。
void QCardLayout::setGeometry(const QRect &r)
{
    QLayout::setGeometry(r);

    if (list.size() == 0)
        return;

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

// sizeHint()和minimumSize()通常非常相似。这两个函数返回的尺寸应包括spacing(),但不包括margin()。
QSize QCardLayout::sizeHint() const
{
    QSize s(0,0);
    int n = list.count();
    if (n > 0)
        s = QSize(100,70);
    int i = 0;
    while (i < n) {
        QLayoutItem *o = list.at(i);
        s = s.expandedTo(o->sizeHint());
        ++i;
    }
    return s + n*QSize(spacing(), spacing());
}

QSize QCardLayout::minimumSize() const
{
    QSize s(0,0);
    int n = list.count();
    int i = 0;
    while (i < n) {
        QLayoutItem *o = list.at(i);
        s = s.expandedTo(o->minimumSize());
        ++i;
    }
    return s + n*QSize(spacing(), spacing());
}

你可能感兴趣的:(qt,Qt布局管理,Qt布局,Qt自定义布局,Qt卡片布局)