(1)本节内容来源于头文件 qlayout . h :
(2)以下给出源码,本文件不太大,友好多了:
#ifndef QLAYOUT_H
#define QLAYOUT_H
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtCore/qobject.h>
#include <QtWidgets/qlayoutitem.h>
#include <QtWidgets/qsizepolicy.h>
#include <QtCore/qrect.h>
#include <QtCore/qmargins.h>
#include <limits.h>
QT_BEGIN_NAMESPACE //说明本 QLayout类建立在 QT的总命名空间里
class QLayout;
class QSize;
class QLayoutPrivate;
//可见,本类并没有继承于 QWidget。
class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem
{
Q_OBJECT //依然插入了此宏
Q_DECLARE_PRIVATE(QLayout)
//这个属性持有布局内小部件之间的间距。
//如果没有显式设置值,则布局的空格继承自父布局,或继承自父小部件的样式设置。
//对于QGridLayout和QFormLayout,可以使用setHorizontalSpacing()和
//setVerticalSpacing()设置不同的水平和垂直间距。在这种情况下,spacing()返回-1。
Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
//返回布局周围使用的边距。
//默认情况下,QLayout使用样式提供的值。在大多数平台上,所有方向的边距均为 11像素。
Q_PROPERTY(QMargins contentsMargins READ contentsMargins
WRITE setContentsMargins RESET unsetContentsMargins)
//This property holds the resize mode of the layout。
//The default mode is SetDefaultConstraint. 返回值的枚举类型就定义在本类
Q_PROPERTY(SizeConstraint sizeConstraint
READ sizeConstraint WRITE setSizeConstraint)
private:
Q_DISABLE_COPY(QLayout) //看起来是禁止对本类的 copy构造
static void activateRecursiveHelper(QLayoutItem *item);//无官方注释
friend class QApplicationPrivate; //声明了两个友元类
friend class QWidget;
protected:
void widgetEvent(QEvent * );
void childEvent(QChildEvent * e) override;
QLayout(QLayoutPrivate & d, QLayout *, QWidget *); //无注释
public:
enum SizeConstraint { //容器内控件大小的控制策略,固定或者变化
SetDefaultConstraint,
SetNoConstraint,
SetMinimumSize,
SetFixedSize,
SetMaximumSize,
SetMinAndMaxSize
};
Q_ENUM(SizeConstraint) //把上面自定义的枚举类注册到QT 的元对象系统
//Constructs a new top-level QLayout, with parent parent.
//The layout is set directly as the top-level layout for parent.
//There can be only one top-level layout for a widget.
//It is returned by QWidget::layout().
//If parent is nullptr, then you must insert this layout into another layout,
//or set it as a widget's layout using QWidget::setLayout().
//---->使用举例 gridLayout->addWidget(label, 0, 0, 1, 1);
//----> verticalLayout->addLayout(gridLayout);//网格布局被添加入窗体的垂直布局
explicit QLayout(QWidget *parent = nullptr); //本类的构造函数:某窗体将采用本布局
~QLayout(); //依然是虚的析构函数
//Q_PROPERTY(SizeConstraint sizeConstraint 组件的大小控制
// READ sizeConstraint WRITE setSizeConstraint)
SizeConstraint sizeConstraint() const;
void setSizeConstraint(SizeConstraint);
//Q_PROPERTY(int spacing READ spacing WRITE setSpacing) 布局内组件之间的间距
virtual int spacing() const;
virtual void setSpacing(int);
//Q_PROPERTY(QMargins contentsMargins READ contentsMargins 内容边缘的空白
// WRITE setContentsMargins RESET unsetContentsMargins)
QMargins contentsMargins() const;
void setContentsMargins(int left, int top, int right, int bottom);
void setContentsMargins(const QMargins &margins);
void unsetContentsMargins();
void getContentsMargins(int *left , int *top,
int *right, int *bottom) const;
//Returns the menu bar set for this layout, or nullptr if no menu bar is set.
QWidget * menuBar() const; //返回为当前布局设置的菜单栏,如果没有设置菜单栏则为 nullptr。
void setMenuBar(QWidget * w); // w 是为窗口添加的菜单栏
//告诉几何管理器将菜单栏 w 放置在parentWidget()的顶部,
//位于QWidget::contentsMargins()之外。所有子小部件都放置在菜单栏底部边缘的下方。
//Tells the geometry manager to place the menu bar widget at the top of
//parentWidget(), outside QWidget::contentsMargins().
//All child widgets are placed below the bottom edge of the menu bar.
protected:
//返回当此布局的几何形状设置为 r时应该覆盖的矩形,前提是此布局支持setAlignment()
//结果由sizeHint()和expand()得出。它永远不会大于r。
QRect alignmentRect(const QRect & r) const;
// class QRect { int x1; int y1; int x2; int y2; }
public:
//Returns the layout's geometry() rectangle, 返回布局中内容所占据的矩形区域
//but taking into account the contents margins. 但也包括内容边缘的空白
QRect contentsRect() const;
QRect geometry() const override;
//Returns the rectangle covered by this layout item.
virtual void setGeometry(const QRect&) override;
//Returns true if the layout is enabled; otherwise returns false.
bool isEnabled() const;
void setEnabled(bool enable);
//Enables this layout if enable is true, otherwise disables it.
//An enabled layout adjusts dynamically to changes;
//a disabled layout acts as if it did not exist.
//By default all layouts are enabled.
bool isEmpty() const override; //查看本容器内是否为空,这是继承来的虚函数
QLayout * layout() override; //返回的还是本布局类型:网格布局、垂直布局、水平布局等
QSizePolicy::ControlTypes controlTypes() const override;//返回控件类型:按钮复选框等
//返回值是 Qt::Vertical 或 Qt::Horizontal,布局内控件的增大伸展方向
Qt::Orientations expandingDirections() const override;
//返回此布局的父布局,如果此布局未安装在任何布局上,则为nullptr。
//如果布局是子布局,则此函数返回父布局的父控件。
//Returns the parent widget of this layout, or nullptr if
//this layout is not installed on any widget.
//If the layout is a sub-layout,
//this function returns the parent widget of the parent layout.
QWidget * parentWidget() const ; //返回布局依赖的窗体容器组件
//QObject * QObject::parent() { return d_ptr->parent; }//显示本对象所在的容器
//QMetaObject * QMetaObject::superClass() ; //返回继承父类
//Returns a size that satisfies all size constraints on w,
//including heightForWidth() and that is as close as possible to s.
static QSize closestAcceptableSize(const QWidget * w, const QSize & s);
//class QSize { int wd; int ht; }
QSize minimumSize() const override; //返回自己的最小尺寸
QSize totalMinimumSize() const; //无官方注释
QSize maximumSize() const override; //返回自己的最大尺寸
QSize totalMaximumSize() const; //无官方注释
QSize totalSizeHint () const; //无官方注释
int totalHeightForWidth (int w) const; //无官方注释
int totalMinimumHeightForWidth(int w) const; //无官方注释
//无效化此布局项中的任何缓存信息。 以上的成员函数全是读信息,以下的成员函数全是写入数据的
void invalidate() override; //Reimplements: QLayoutItem::invalidate().
bool activate(); //如果需要,重新布局parentWidget()
//通常你不需要调用这个函数,因为它会在最合适的时间自动调用。如果布局被重做,它会返回true。
//通常你不需要调用这个函数,因为它会在最合适的时间自动调用。
void update (); //更新父 widget()的布局。
//Sets the alignment for widget w to alignment形参 and
//returns true if w is found in this layout (not including child layouts);
//otherwise returns false.
bool setAlignment(QWidget *w, Qt::Alignment alignment);
bool setAlignment(QLayout *l, Qt::Alignment alignment);
//Sets the alignment for the layout l to alignment and returns true if
//l is found in this layout (not including child layouts);
//otherwise returns false.
using QLayoutItem::setAlignment; //将本 QLayoutItem设置为形参指定的方式
void addWidget(QWidget *w);
void removeWidget(QWidget *w);
virtual QLayoutItem * replaceWidget(QWidget *from, QWidget *to,
Qt::FindChildOptions options = Qt::FindChildrenRecursively);
virtual void addItem(QLayoutItem *) = 0; //形参是最终的基类
void removeItem(QLayoutItem *);
protected :
bool adoptLayout(QLayout *layout); //无官方注释
void addChildLayout(QLayout *l);
//此函数从子类的addLayout()或insertLayout()函数中调用,以添加布局 l 作为子布局。
//唯一需要直接调用它的场景是,如果你实现了一个支持嵌套布局的定制布局。
void addChildWidget(QWidget * w);
//This function is called from addWidget() functions in subclasses to
//add w as a managed widget of a layout.
//If w is already managed by a layout,
//this function will give a warning and remove w from that layout.
//This function must therefore be called before adding w to the
//layout's data structure.
public :
virtual int count () const = 0;
virtual int indexOf(const QWidget *) const;
virtual int indexOf(const QLayoutItem *) const;
virtual QLayoutItem * itemAt(int index) const = 0;
virtual QLayoutItem * takeAt(int index) = 0; //专职删除布局内的控件
//必须在子类中实现以从布局中移除 index处的布局项,并返回该项。
//如果没有这样的项,则该函数必须什么也不做并返回0。项从0开始连续编号。
//如果移除项,则其他项将重新编号。
/* //以下代码片段显示了一种安全地从布局中删除所有项的方法:
QLayoutItem *child;
while ( (child = layout->takeAt(0)) != nullptr ) {
...
delete child->widget(); // delete the widget
delete child; // delete the layout item
}
*/
}; //完结 class QLayout : public QObject, public QLayoutItem
// class QWidget : public QObject, public QPaintDevice
QT_END_NAMESPACE
//### support old includes
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qgridlayout.h>
#endif // QLAYOUT_H
(3) 布局里可以直接加入子布局或子容器 :
(4)
谢谢