QT6 源(38):布局类的总基类 QLayoutItem 的源码,以及其两个直接子类的源码 QWidgetItem,QSpacerItem

(1)先给出布局系列组件的类继承关系

在这里插入图片描述

(2)

#ifndef QLAYOUTITEM_H
#define QLAYOUTITEM_H

#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qsizepolicy.h>
#include <QtCore/qrect.h>

#include <limits.h>

QT_BEGIN_NAMESPACE //说明本基类依然定义在 QT 的总命名空间里


inline constexpr int QLAYOUTSIZE_MAX = INT_MAX/256/16; //定义了一个很大的全局量

class QLayout;
class QLayoutItem;
class QSpacerItem;
class QWidget;
class QSize;

enum AlignmentFlag
{
    AlignLeft     = 0x0001,
    AlignLeading  = AlignLeft,
    AlignRight    = 0x0002,
    AlignTrailing = AlignRight,
    AlignHCenter  = 0x0004,
    AlignJustify  = 0x0008,
    AlignAbsolute = 0x0010,
    AlignHorizontal_Mask = AlignLeft | AlignRight |
                           AlignHCenter | AlignJustify | AlignAbsolute,

    AlignTop      = 0x0020,
    AlignBottom   = 0x0040,
    AlignVCenter  = 0x0080,
    AlignBaseline = 0x0100,

    AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter | AlignBaseline,

    AlignCenter = AlignVCenter | AlignHCenter
};
Q_DECLARE_FLAGS(Alignment, AlignmentFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(Alignment)
//可见 Alignment = QFlags<AlignmentFlag>

class Q_WIDGETS_EXPORT QLayoutItem
{
protected:
    Qt::Alignment align;  //这个数据成员是枚举类 QFlags<T> 的实例对象
public:
    //本类的构造函数
    inline explicit QLayoutItem(Qt::Alignment alignment = Qt::Alignment())
        : align(aalignment) { }

    virtual ~QLayoutItem(); //虚析构函数

    //Returns the alignment of this item.
    Qt::Alignment alignment() const { return align; }
    void       setAlignment(Qt::Alignment alignment);
    //将此项目的对齐方式设置为 alignment 方式。
    //注:仅在具有视觉效果的 QLayoutItem 子类中才支持项对齐。
    //除了为布局提供空白空间的 QSpacerItem 之外,
    //所有继承 QLayoutltem 的公共 Qt 类都支持项对齐 item alignment。

    //Implemented in subclasses to return the minimum size of this item.
    virtual QSize minimumSize() const = 0;

    //Implemented in subclasses to return the maximum size of this item.
    virtual QSize maximumSize() const = 0;

    //Implemented in subclasses to return the preferred size of this item.
    virtual QSize sizeHint   () const = 0;

/*
    enum Orientation { Horizontal = 0x1, Vertical = 0x2 };
    Q_DECLARE_FLAGS(Orientations, Orientation)
    一样推导出本函的返回值类型是 Orientations = QFlags<Orientation>
*/
    virtual Qt::Orientations expandingDirections() const = 0;
    //返回该布局项是否可以使用比 sizeHint ()更多的空间。
    //Qt::Vertical或 Qt::Horizontal的值表示它只想在一个维度上增长,
    //而 Qt:Vertical Ot::Horizontal的值表示它想在两个维度上增长。

    //Implemented in subclasses to return whether this item is empty,
    //i.e. whether it contains any widgets.
    virtual bool isEmpty() const = 0;

    //Returns the rectangle covered by this layout item.
    virtual QRect   geometry() const = 0;
    virtual void setGeometry(const QRect & r) = 0;
    //Implemented in subclasses to set this item's geometry to r.

    //Invalidates any cached information in this layout item.
    virtual void invalidate(); //无效化此布局项中的任何缓存信息。

    //返回此布局项的首选高度,给定宽度,这在默认实现中未使用。
    //默认实现返回-1,表示首选高度与项的宽度无关。
    //使用hasHeightForWidth()函数通常比调用此函数并测试-1要快得多。
    //强烈建议使用缓存,否则布局将需要指数级时间。
    virtual int         heightForWidth( int ) const;
    virtual bool     hasHeightForWidth(     ) const;
    //如果此布局的偏好高度取决于其宽度,则返回 true;否则返回 false。默认实现返回 false。
    //在支持高度为宽度的布局管理器中重新实现此函数。
    virtual int  minimumHeightForWidth(int w) const;
    //返回此小部件在给定宽度w下所需的最低高度。默认实现只是返回heightForWidth(w)

    //如果此项管理一个QWidget,则返回该widget。否则,返回nulptr。
    //注:虽然函数layout()和spacerltem()执行类型转换,
    //但这个函数返回另一个对象:QLayout和 QSpacerltem 继承自 QLayoutltem,而QWidget不继承。
    virtual QWidget * widget() const;

    //如果此项是QLayout,则返回QLayout;否则返回nullptr。此函数提供类型安全的转换。
    virtual QLayout * layout();

    //如果此项是QSpacerltem,则返回QSpacerltem;否则返回nullptr。此函数提供类型安全的转换。
    virtual QSpacerItem * spacerItem();
    //class QSpacerItem : public QLayoutItem 定义就在下面

    //返回布局项的控制类型。对于QWidgetltem,控制类型来自小部件的大小策略 size policy;
    //对于QLayoutltem,控制类型来自布局的内容。本函的返回值全是控件类型
    virtual QSizePolicy::ControlTypes controlTypes() const; //详情见下面的
};

class Q_WIDGETS_EXPORT QSizePolicy
{
public:
    enum ControlType {
        DefaultType      = 0x00000001,
        ButtonBox        = 0x00000002,
        CheckBox         = 0x00000004,
        ComboBox         = 0x00000008,
        Frame            = 0x00000010,
        GroupBox         = 0x00000020,
        Label            = 0x00000040,
        Line             = 0x00000080,
        LineEdit         = 0x00000100,
        PushButton       = 0x00000200,
        RadioButton      = 0x00000400,
        Slider           = 0x00000800,
        SpinBox          = 0x00001000,
        TabWidget        = 0x00002000,
        ToolButton       = 0x00004000
    };
    Q_DECLARE_FLAGS(ControlTypes, ControlType)
    Q_FLAG(ControlTypes)
    //可见 ControlTypes = QFlags<ControlType>

    enum Policy {
        Fixed     = 0,
        Minimum   = GrowFlag,
        Maximum   = ShrinkFlag,
        Preferred = GrowFlag | ShrinkFlag,
        MinimumExpanding = GrowFlag | ExpandFlag,
        Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
        Ignored   = ShrinkFlag | GrowFlag | IgnoreFlag
    };
    Q_ENUM(Policy) //似乎是完善枚举运算的
};

class Q_WIDGETS_EXPORT QWidgetItem : public QLayoutItem
{
    Q_DISABLE_COPY(QWidgetItem)
protected:
    QWidget * wid; //本类的数据成员,在继承排序的基础上,多了个控件指针

public:
    explicit QWidgetItem(QWidget *w) : wid(w) { } //构造与析构函数
    ~QWidgetItem();

    QSize sizeHint() const override;  //这些函数重载,是不改变语义的
    QSize minimumSize() const override;
    QSize maximumSize() const override;
    Qt::Orientations expandingDirections() const override;

    //Returns true if the widget is hidden; otherwise returns false.
    bool isEmpty() const override;

    void setGeometry(const QRect&) override;
    QRect geometry() const override;

    //Returns the widget managed by this item.
    QWidget *widget() const override;

    bool hasHeightForWidth() const override;
    int heightForWidth(int) const override;
    int minimumHeightForWidth(int) const override;

    //Returns the control type associated with the widget for which
    //this size policy applies.
    QSizePolicy::ControlTypes controlTypes() const override;

};

class Q_WIDGETS_EXPORT QSpacerItem : public QLayoutItem //本类的子类
{  
private:
    int         width ;
    int         height;
    QSizePolicy sizeP ;
    QRect       rect  ;
public:
    QSpacerItem(int w, int h, //关于 QSizePolicy::Policy类型的介绍在上面
                 QSizePolicy::Policy hData = QSizePolicy::Minimum,
                 QSizePolicy::Policy vData = QSizePolicy::Minimum)
        : width(w), height(h), sizeP(hData, vData) { }

    ~QSpacerItem();

    bool  isEmpty() const override; //Returns true. 重定义
    QSpacerItem * spacerItem() override; //Returns a pointer to this object.
    QSizePolicy   sizePolicy() const { return sizeP; }
    //Returns the size policy of this item.

    QSize sizeHint() const override;
    QSize minimumSize() const override;
    QSize maximumSize() const override;
    Qt::Orientations expandingDirections() const override;
    void setGeometry(const QRect&) override;
    QRect geometry() const override;


    //将此间隔项更改为具有首选宽度w、首选高度h、水平尺寸策略hPolicy和垂直尺寸策略vPolicy。
    //默认值提供了一个间隙,如果没有任何其他东西想要这个空间,这个间隙可以拉伸。
    //请注意,如果在布局中添加间隔项后调用 changeSize(),则必须无效化布局,以便间隔项的新大小生效。
    void changeSize(int w, int h,
                     QSizePolicy::Policy hData = QSizePolicy::Minimum,
                     QSizePolicy::Policy vData = QSizePolicy::Minimum);
};

class Q_WIDGETS_EXPORT QWidgetItemV2 : public QWidgetItem
{
public:
    explicit QWidgetItemV2(QWidget *widget);
    ~QWidgetItemV2();

    QSize sizeHint() const override;
    QSize minimumSize() const override;
    QSize maximumSize() const override;
    int heightForWidth(int width) const override;

private:
    enum { Dirty = -123, HfwCacheMaxSize = 3 };

    inline bool useSizeCache() const;
    void updateCacheIfNecessary() const;
    inline void invalidateSizeCache() {
        q_cachedMinimumSize.setWidth(Dirty);
        q_hfwCacheSize = 0;
    }

    mutable QSize q_cachedMinimumSize;
    mutable QSize q_cachedSizeHint;
    mutable QSize q_cachedMaximumSize;
    mutable QSize q_cachedHfws[HfwCacheMaxSize];
    mutable short q_firstCachedHfw;
    mutable short q_hfwCacheSize;
    void *d;

    friend class QWidgetPrivate;

    Q_DISABLE_COPY(QWidgetItemV2)
};

QT_END_NAMESPACE

#endif // QLAYOUTITEM_H

(3)

谢谢

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhangzhangkeji

谢谢支持

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

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

打赏作者

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

抵扣说明:

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

余额充值