zoukankan      html  css  js  c++  java
  • QAbstractItemModel使用样例与解析(Model::index使用了createIndex,它会被销毁吗?被销毁了,因为栈对象出了括号就会被销毁)

    参考:qt源码
    qstandarditemmodel_p.h
    qstandarditemmodel.h
    qstandarditemmodel.cpp
    qabstractitemmodel.h
    qabstractitemmodel.cpp

    QAbstractItemModel是一个接口类,使用时需要从它继承下来,实现相关的函数后使用。
    不同于QStandardItemModel,使用QAbstractItemModel的话,需要自己构造树形结构数据,并在虚函数中返回对应的值。

    当然,简单使用的话,也可以快速构造出没有父节点的简单表格结构。
    形如根节点下列了几排几列子节点的表格情形。

    需要继承的类有:

    class HistoryModel : public QAbstractItemModel
    {
    public:
    explicit HistoryModel(QObject *parent = 0);

    // 构造父节点下子节点的索引
    virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    // 通过子节点索引获取父节点索引
    virtual QModelIndex parent(const QModelIndex &child) const override;
    // 获取父节点下子节点的行数
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    // 获取父节点下子节点列数
    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    // 获取节点数据:包括DisplayRole|TextAlignmentRole等
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    };
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    实现几排几列表格情形的例子:

    HistoryModel::HistoryModel(QObject *parent /*= 0*/)
    : QAbstractItemModel(parent)
    {
    }

    QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const
    {
    // 创建普通索引
    return createIndex(row, column);
    }
    QModelIndex HistoryModel::parent(const QModelIndex &child) const
    {
    // 父节点均为跟节点
    return QModelIndex();
    }
    int HistoryModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const
    {
    // 根节点下有5行,其它行下没有
    if (parent.row() == -1)
    {
    return 5;
    }
    return 0;
    }
    int HistoryModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const
    {
    // 每行有量列
    return 2;
    }

    QVariant HistoryModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const
    {
    // 节点内容:左对齐,显示行列号
    if (role == Qt::TextAlignmentRole)
    return int(Qt::AlignLeft | Qt::AlignVCenter);
    else if (role == Qt::DisplayRole)
    return QString("row=%1,col=%2").arg(index.row()).arg(index.column());
    else
    return QVariant();
    }
    进一步使用,添加树形结构,自己构造树形结构数据:

    struct NodeInfo
    {
    QModelIndex parent; // 父节点index
    QString sData; // 自身数据
    QVector<NodeInfo*> childNodes; // 子节点
    NodeInfo(QModelIndex parentIdx, QString s):parent(parentIdx), sData(s){}
    };
    1
    2
    3
    4
    5
    6
    7
    生成如下的这种界面:两个level=1节点,每个节点下有一些数据

    可以这样来做:
    每个节点存储一个NodeInfo信息,这样
    1. 每个节点可以查询子节点数量
    2. 每个节点可以查询到自身数据
    3. 可以根据NodeInfo信息(row/col/this)获取到QModeIndex
    4. 数据构造时,形成NodeInfo的树形层次
    5. QAbstractItemModel的接口中,index函数中绑定NodeInfo
    6. QAbstractItemModel的其它接口中,查询NodeInfo并使用

    HistoryModel::HistoryModel(QObject *parent /*= 0*/)
    : QAbstractItemModel(parent)
    {
    // 创建root节点
    m_pRootNode = new NodeInfo(nullptr, "rootNode", -1, -1);
    m_receiveInfo = new NodeInfo(m_pRootNode, "ReceiveMessage", 0, 0);
    m_replyInfo = new NodeInfo(m_pRootNode, "ReplyMessage", 1, 0);
    m_pRootNode->childNodes.append(m_receiveInfo);
    m_pRootNode->childNodes.append(m_replyInfo);
    }

    QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const
    {
    if (parent.row() == -1 && parent.column() == -1)
    {
    // 首层节点绑定关系
    if (row < m_pRootNode->childNodes.count())
    return createIndex(row, column, m_pRootNode->childNodes[row]);
    }
    else
    {
    // 其它层节点绑定关系
    if (parent.internalPointer() != nullptr)
    {
    NodeInfo* pNode = reinterpret_cast<NodeInfo*>(parent.internalPointer());
    if (pNode->childNodes.size() > row)
    {
    return createIndex(row, column, pNode->childNodes[row]);
    }
    }
    }
    return QModelIndex();
    }

    QModelIndex HistoryModel::parent(const QModelIndex &child) const
    {
    if (child.internalPointer() != nullptr)
    {
    NodeInfo* pNode = reinterpret_cast<NodeInfo*>(child.internalPointer());
    NodeInfo* pParent = pNode->parent;
    if (pParent != nullptr)
    {
    // 根据父节点信息:row/col/node*获取Index
    return createIndex(pParent->nRow, pParent->nCol, pParent);;
    }
    }
    return QModelIndex();
    }
    int HistoryModel::rowCount(const QModelIndex &parent) const
    {
    if (parent.internalPointer() == nullptr)
    {
    // 根节点下的数据行数
    return m_pRootNode->childNodes.count();
    }
    else
    {
    // 节点下的数据行数
    NodeInfo* pNode = reinterpret_cast<NodeInfo*>(parent.internalPointer());
    return pNode->childNodes.size();
    }
    }
    int HistoryModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const
    {
    // 每行有量列
    return 1;
    }

    QVariant HistoryModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const
    {
    // 节点内容:左对齐,显示行列号
    if (role == Qt::TextAlignmentRole)
    {
    return int(Qt::AlignLeft | Qt::AlignVCenter);
    }
    else if (role == Qt::DisplayRole)
    {
    if (index.internalPointer() == 0)
    {
    return QString("row=%1,col=%2").arg(index.row()).arg(index.column());
    }
    else
    {
    NodeInfo* pNode = reinterpret_cast<NodeInfo*>(index.internalPointer());
    return pNode->sData;
    }
    }
    else
    {
    return QVariant();
    }
    }
    (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
    ---------------------
    作者:春夜喜雨
    来源:CSDN
    原文:https://blog.csdn.net/chunyexiyu/article/details/77657624
    版权声明:本文为博主原创文章,转载请附上博文链接!

    void wokr()
    {
        QModelIndex index = model.getIndex();
        ...
        ...
        return;
       // 局部变量,函数退出时自动回收。
    }
    
    std::string func()
    {
    return "123";
    }
    你需要管返回值谁释放嘛?
    
    奇怪的问题
    
    std::string* func()
    {
    return new std::string("123");
    }
    但是这个你就要关心了
  • 相关阅读:
    python爬虫之urllib
    python 数据库操作类
    Vue学习之路第十篇:简单计算器的实现
    Vue学习之路第九篇:双向数据绑定 v-model指令
    Vue学习之路第八篇:事件修饰符
    Vue学习之路第七篇:跑马灯项目实现
    Vue学习之路第六篇:v-on
    Vue学习之路第五篇:v-bind
    Vue学习之路第四篇:v-html指令
    Vue学习之路第三篇:插值表达式和v-text的区别
  • 原文地址:https://www.cnblogs.com/findumars/p/11140057.html
Copyright © 2011-2022 走看看