zoukankan      html  css  js  c++  java
  • Qt之自定义布局管理器(QCardLayout)

    简述

    手动布局另一种方法是通过继承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 = 0);
        ~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(0)))
            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 >= 0 && idx < list.size() ? list.takeAt(idx) : 0;
    }
    
    // 添加项目
    void QCardLayout::addItem(QLayoutItem *item)
    {
        list.append(item);
    }
    
    // 实际控制着布局,作为参数提供的矩形不包括margin()。相关的,使用spacing()作为项目之间的距离。
    void QCardLayout::setGeometry(const QRect &r)
    {
        QLayout::setGeometry(r);
    
        if (list.size() == 0)
            return;
    
        int w = r.width() - (list.count() - 1) * spacing();
        int h = r.height() - (list.count() - 1) * spacing();
        int i = 0;
        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(0,0);
        int n = list.count();
        if (n > 0)
            s = QSize(100,70);
        int i = 0;
        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(0,0);
        int n = list.count();
        int i = 0;
        while (i < n) {
            QLayoutItem *o = list.at(i);
            s = s.expandedTo(o->minimumSize());
            ++i;
        }
        return s + n*QSize(spacing(), spacing());
    }
  • 相关阅读:
    Hibernate映射之数组属性, 集合属性(list、set和map)
    org.hibernate.type.SerializationException: could not deserialize 反序列化失败
    linux下同一个tomcat部署多个项目
    Nexus私服 Maven
    maven 父子项目 聚合与继承 生命周期 打包插件 依赖打包 jar pom war
    IDEA中创建Web聚合项目(Maven多模块项目)
    为什么要在linux命令前加上 ./ 什么时候才需要在命令前加上./
    web.xml 介绍 and pom.xml 介绍
    有趣的linux命令
    SpringMVC 中常见注释
  • 原文地址:https://www.cnblogs.com/itrena/p/5938331.html
Copyright © 2011-2022 走看看