QT6 源(40):类 QLayout 的源码 : QObject , QLayoutItem。布局里可以直接加入子布局或子容器,

(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)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值