自定义布局管理器

要编写自定义布局管理器,需要从QLayout类派生,并定义如下一些方法和数据结构:

  • 存储布局管理器上每个项的数据结构,每个项是一个QLayoutItem

  • addItem(),定义怎样将每个项添加到布局管理器上。

  • setGeometry(),怎样执行布局。

  • sizeHint(),布局管理器优先选择的大小。

  • itemAt(),怎样在布局管理器中抚今迭代这些项。

  • takeAt(),怎样从布局管理器中删除这些项。

  • 在大部分情况下,还需要实现minimumSize()方法。

下面是一个实现自定义布局管理器的实例, 称为CardLayout。

头文件:

#ifndef CARDLAYOUT_H
#define CARDLAYOUT_H

#include <QWidget>
#include <QLayout>
#include <QList>

class CardLayout : public QLayout
{
    Q_OBJECT
public:
    explicit CardLayout(QWidget *parent = 0, int margin = 0, int dist=-1);
    ~CardLayout();

    void addItem(QLayoutItem *);
    QSize sizeHint() const;
    QSize minimumSize() const;
    int count() const;
    QLayoutItem *itemAt(int index) const;
    QLayoutItem *takeAt(int index);
    void setGeometry(const QRect &);

private:
    QList<QLayoutItem*> list;

};

#endif // CARDLAYOUT_H

实现文件:

#include "cardlayout.h"

CardLayout::CardLayout(QWidget *parent,
                       int margin, int dist) :
    QLayout(parent)
{
    setMargin(margin);
    setSpacing(dist);
}

CardLayout::~CardLayout()
{
    QLayoutItem *item;
    while ((item = takeAt(0)))
        delete item;
}

int CardLayout::count() const
{
    // returns the number of QLayoutItems
    return list.size();
}

QLayoutItem *CardLayout::itemAt(int index) const
{
    return list.value(index);
}

QLayoutItem *CardLayout::takeAt(int index)
{
    return index >= 0 && index < list.size() ? list.takeAt(index) : 0;
}

void CardLayout::addItem(QLayoutItem *item)
{
    list.append(item);
}

void CardLayout::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;
    }
}

QSize CardLayout::sizeHint() const
{
    QSize s(0, 0);
    int n = list.count();
    if (n > 0)
        s = QSize(100, 70);//start with a nice default size
    int i = 0;
    while (i < n) {
        QLayoutItem *o = list.at(i);
        s = s.expandedTo(o->sizeHint());
        ++i;
    }
    return s + n * QSize(spacing(), spacing());
}

QSize CardLayout::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->sizeHint());
        ++i;
    }
    return s + n * QSize(spacing(), spacing());
}

测试代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel *l1 = new QLabel("label1");
    QLabel *l2 = new QLabel("label2");
    QLabel *l3 = new QLabel("label3");
    QLabel *l4 = new QLabel("label4");

    CardLayout *layout = new CardLayout;
    layout->addItem(new QWidgetItem(l1));
    layout->addItem(new QWidgetItem(l2));
    layout->addWidget(l3);
    layout->addWidget(l4);

    qDebug()<<"count: "<<layout->count();

    QWidget *central = new QWidget(this);
    central->setLayout(layout);
    setCentralWidget(central);
}



你可能感兴趣的:(数据结构,list,测试,layout,delete,存储)