簡述
手動布局另一種方法是通過繼承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 = );
~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());
}