天天看點

Qt 之自定義布局管理器(QCardLayout)簡述定義實作

簡述

手動布局另一種方法是通過繼承QLayout類編寫自己的布局管理器。

下面我們詳細來舉一個例子-QCardLayout。它由同名的Java布局管理器啟發而來。也被稱之為卡片布局,每個項目偏移QLayout::spacing()。

|

版權聲明:一去、二三裡,未經部落客允許不得轉載。

定義

編寫自己的布局,必須定義如下:

  • 一種存儲布局處理項目的資料結構,每個項目都是一個QLayoutItem,本例使用QList。
  • addItem() 如何添加項目布局。
  • setGeometry() 如何控制布局。
  • sizeHint() 布局的優選大小。
  • itemAt() 如何周遊布局。
  • takeAt() 如何删除布局中的項目。

大多數情況下,也會實作的minimumSize()。

實作

效果

Qt 之自定義布局管理器(QCardLayout)簡述定義實作

源碼

QCardLayoud.h

#ifndef QCARDLAYOUT_H
#define QCARDLAYOUT_H

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

class QCardLayout : public QLayout
{
public:
    QCardLayout(QWidget *parent = );
    ~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()))
        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 >=  && idx < list.size() ? list.takeAt(idx) : ;
}

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

// 實際控制着布局,作為參數提供的矩形不包括margin()。相關的,使用spacing()作為項目之間的距離。
void QCardLayout::setGeometry(const QRect &r)
{
    QLayout::setGeometry(r);

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

    int w = r.width() - (list.count() - ) * spacing();
    int h = r.height() - (list.count() - ) * spacing();
    int i = ;
    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(,);
    int n = list.count();
    if (n > )
        s = QSize(,);
    int i = ;
    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(,);
    int n = list.count();
    int i = ;
    while (i < n) {
        QLayoutItem *o = list.at(i);
        s = s.expandedTo(o->minimumSize());
        ++i;
    }
    return s + n*QSize(spacing(), spacing());
}
           

繼續閱讀