QT Layout

1、QT自带Layout

     QLayoutItem是所有布局的基类,子类的继承关系如下:
      1.1、QLayout
             1.1.1、QBoxLayout

                       盒子布局,
                       1.1.1.1、QHBoxLayout

                                    水平盒子布局,所有的widget都水平方向排列;
                       1.1.1.2、QVBoxLayout

                                    垂直盒子布局,所有的widget都垂直方向排列;
              1.1.2、QFormLayout

                        表单布局,正如表单一样,行数可变,但每行都只有两列;

                        每行都包含一个名称/值形式,名称对应LabelWidget,值对应Edit、ComboBox等widget;

              1.1.3、QGridLayout

                        表格布局,可以是多行多列;
              1.1.4、QStackedLayout

                        堆布局;

      1.2、QSpacerItem
      1.3、QWidgetItem

 

 

 

2、QLayoutItem类介绍

     /* 构造函数,指明对齐方式 */

     QLayoutItem ( Qt::Alignment alignment = 0 )
     virtual ~QLayoutItem ()

 

     /*对齐方式 */

     void setAlignment ( Qt::Alignment alignment )
     Qt::Alignment alignment () const

 

    /* 几何位置 */

    virtual void setGeometry ( const QRect & r ) = 0

    virtual QRect geometry () const = 0


    QSizePolicy::ControlTypes controlTypes () const
    virtual Qt::Orientations expandingDirections () const = 0

 

    /* Height是否和Width关联,如果相关联,则heightForWidth指明了这种关联 */

    virtual bool hasHeightForWidth () const
    virtual int heightForWidth ( int w ) const


    virtual void invalidate ()

 

 

    /* 该Item是否为空,也就是说该Item是否包含子Widget */
    virtual bool isEmpty () const = 0


    /* 返回和宽度w对应的最小Height */
    virtual int minimumHeightForWidth ( int w ) const

    /* 返回该Item的最佳Size */
    virtual QSize sizeHint () const = 0

 

    /* 返回该Item的最大/小Size */

    virtual QSize minimumSize () const = 0

    virtual QSize maximumSize () const = 0

 

    /* 如果该Item是一个QSpacerItem,则返回QSpacerItem */

    /* 如果该Item是一个QWidget,则返回QWidget */

    /* 如果该Item是一个LayOut,则返回QLayOut */

    /* 主要在类型安全转换时使用 */

    virtual QSpacerItem * spacerItem ()

    virtual QLayout * layout ()
    virtual QWidget * widget ()

 

 

3、QLayout类介绍

    /* 向Layout添加对象 */

    virtual void addItem ( QLayoutItem * item ) = 0
    void addWidget ( QWidget * w )

    /* 对象个数 */

    virtual int count () const = 0

    /* 根据Index确定对应的Widget,根据Widget确定对应的Index */
    virtual int indexOf ( QWidget * widget ) const
    virtual QLayoutItem * itemAt ( int index ) const = 0

 

    /* 根据Index确定对应的Item,类似于itemAt */
    virtual QLayoutItem * takeAt ( int index ) = 0

 

    /* 告诉Geometry Manager将widget菜单条关联到Layout的parentWidget上,

        例如:layout是dialog的mainlayout,则layout->setMenuBar(widget)会将widget菜单条关联到dialog上,也就是dialog的菜单条 */

    QWidget * parentWidget () const

    QWidget * menuBar () const

    void setMenuBar ( QWidget * widget )

 

4、自定义Layout

    自定义Layout,就是从QLayoutItem派生。

    BorderLayout包括东西南北中五个方位,可以向不同方位添加元素;

    头文件:

    class BorderLayout : public QLayout
    {
        public:

            /* 位置方位:东西南北中五个方位 */
            enum Position { West, North, South, East, Center };

 

            /* 构造,析构 */

            BorderLayout(QWidget *parent, int margin = 0, int spacing = -1);
            BorderLayout(int spacing = -1);
            ~BorderLayout();

 

            /* 从QLayout类派生的方法 */

            /* 添加Widget和Item */

            void addItem(QLayoutItem *item);
            void addWidget(QWidget *widget, Position position);
            /* 扩展方向 */

            Qt::Orientations expandingDirections() const;

            int count() const;
            QLayoutItem *itemAt(int index) const;
            QLayoutItem *takeAt(int index);

 

            /* 从QLayoutItem类派生的方法 */
           bool hasHeightForWidth() const;

           QSize minimumSize() const;

           void setGeometry(const QRect &rect);
           QSize sizeHint() const;


           void add(QLayoutItem *item, Position position);

    private:
        struct ItemWrapper
        {

            /* BorderLayout布局元素:元素自身、位置信息 */
            ItemWrapper(QLayoutItem *i, Position p)

            {
                item = i;
                position = p;
            }

            QLayoutItem *item;
            Position position;
       };

 

        enum SizeType { MinimumSize, SizeHint };

 

        /* 根据类型,计算BorderLayout的Size */
        QSize calculateSize(SizeType sizeType) const;

 

        /* 所有的BorderLayout元素,保存在链表list中 */

        QList<ItemWrapper *> list;


    };

 

 

    CPP文件

    BorderLayout::BorderLayout(QWidget *parent, int margin, int spacing)
        : QLayout(parent)
    {
        setMargin(margin);
        setSpacing(spacing);
    }

 

    BorderLayout::BorderLayout(int spacing)
    {
        setSpacing(spacing);
    }

 

    /* 析构时,删除list中存在的所有widget */
    BorderLayout::~BorderLayout()
    {
        QLayoutItem *l;
        while ((l = takeAt(0)))
            delete l;
    }

 

    void BorderLayout::addItem(QLayoutItem *item)
    {

        /* 将新item添加到list的尾部,默认方位是西部 */
        add(item, West);
    }

 

    void BorderLayout::addWidget(QWidget *widget, Position position)
    {

        /* 将新widget添加到list的尾部 */
        add(new QWidgetItem(widget), position);
    }

 

    Qt::Orientations BorderLayout::expandingDirections() const
    {
        /* 支持水平和垂直两个方向的扩展 */

        return Qt::Horizontal | Qt::Vertical;
    }

 

    bool BorderLayout::hasHeightForWidth() const
    {
        /* Height和Width没有关联 */

        return false;
    }

 

    int BorderLayout::count() const
    {
        /* 链表长度本质上就是BorderLayout的元素个数 */

        return list.size();
    }

 

     /* 根据index找到相应的元素 */

    QLayoutItem *BorderLayout::itemAt(int index) const
    {
        ItemWrapper *wrapper = list.value(index);
        if (wrapper)
            return wrapper->item;
        else
            return 0;
    }

 

    QSize BorderLayout::minimumSize() const
    {
        /* MinimumSize模式下的Size也就是minimumSize */

        return calculateSize(MinimumSize);
    }

 

    void BorderLayout::setGeometry(const QRect &rect)
    {
        ItemWrapper *center = 0;
        int eastWidth = 0;
        int westWidth = 0;
        int northHeight = 0;
        int southHeight = 0;
        int centerHeight = 0;
        int i;

 

        QLayout::setGeometry(rect);

        for (i = 0; i < list.size(); ++i)

        {
            ItemWrapper *wrapper = list.at(i);
            QLayoutItem *item = wrapper->item;
            Position position = wrapper->position;

 

            if (position == North)

            {
                item->setGeometry(QRect(rect.x(), northHeight, rect.width(),item->sizeHint().height()));

                northHeight += item->geometry().height() + spacing();
            }

            else if (position == South)

            {
                item->setGeometry(QRect(item->geometry().x(),item->geometry().y(), rect.width(),item->sizeHint().height()));

                southHeight += item->geometry().height() + spacing();

                item->setGeometry(QRect(rect.x(),rect.y() + rect.height() - southHeight + spacing(),
                              item->geometry().width(),item->geometry().height()));
            }

            else if (position == Center)

            {
                center = wrapper;
            }
        }

 

        centerHeight = rect.height() - northHeight - southHeight;

        for (i = 0; i < list.size(); ++i)

        {
            ItemWrapper *wrapper = list.at(i);
            QLayoutItem *item = wrapper->item;
            Position position = wrapper->position;

            if (position == West)

            {
                item->setGeometry(QRect(rect.x() + westWidth, northHeight,item->sizeHint().width(), centerHeight));

                westWidth += item->geometry().width() + spacing();
            }

            else if (position == East)

            {
                item->setGeometry(QRect(item->geometry().x(), item->geometry().y(),item->sizeHint().width(), centerHeight));

                eastWidth += item->geometry().width() + spacing();

                item->setGeometry(QRect(rect.x() + rect.width() - eastWidth + spacing(),

                                             northHeight, item->geometry().width(),item->geometry().height()));
            }
        }

 

        if (center)
            center->item->setGeometry(QRect(westWidth, northHeight,rect.width() - eastWidth - westWidth,enterHeight));
    }

 

 

    QSize BorderLayout::sizeHint() const
    {
        return calculateSize(SizeHint);
    }

 

 

QLayoutItem *BorderLayout::takeAt(int index)
{
    if (index >= 0 && index < list.size()) {
        ItemWrapper *layoutStruct = list.takeAt(index);
        return layoutStruct->item;
    }
    return 0;
}

void BorderLayout::add(QLayoutItem *item, Position position)
{
    list.append(new ItemWrapper(item, position));
}

QSize BorderLayout::calculateSize(SizeType sizeType) const
{
    QSize totalSize;

    for (int i = 0; i < list.size(); ++i) {
        ItemWrapper *wrapper = list.at(i);
        Position position = wrapper->position;
        QSize itemSize;

        if (sizeType == MinimumSize)
            itemSize = wrapper->item->minimumSize();
        else // (sizeType == SizeHint)
            itemSize = wrapper->item->sizeHint();

        if (position == North || position == South || position == Center)
            totalSize.rheight() += itemSize.height();

        if (position == West || position == East || position == Center)
            totalSize.rwidth() += itemSize.width();
    }
    return totalSize;
}

 

 

 

 

 

    待补充。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值