Create model for TreeView
-
Hi!
How I can create model for TreeView?
If I do this, then I have only one level in tree:#ifndef BUILDINGTREEMODEL_H #define BUILDINGTREEMODEL_H #include <QObject> #include <QAbstractItemModel> #include "structures.h" class BuildingTreeModel : public QAbstractListModel { Q_OBJECT public: BuildingTreeModel(QObject *parent = nullptr); BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent = nullptr); ~BuildingTreeModel(); enum MarkerRoles{idRole, nameRole, commentRole}; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; void setBuilding(QSharedPointer<BuildingForMap> building); private: QSharedPointer<BuildingForMap> m_building, m_buildingForView; private slots: QVector<int> getDeepIndex(const QModelIndex &index) const; //from childs to parents QSharedPointer<BuildingForMap> getBuildingOnIndex(const QModelIndex &index)const; }; #endif // BUILDINGTREEMODEL_H
#include "buildingtreemodel.h" BuildingTreeModel::BuildingTreeModel(QObject *parent) : QAbstractListModel(parent) { } BuildingTreeModel::BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent) : QAbstractListModel(parent) { setBuilding(building); } BuildingTreeModel::~BuildingTreeModel() { } int BuildingTreeModel::rowCount(const QModelIndex &parent) const { QSharedPointer<BuildingForMap> building = getBuildingOnIndex(parent); qDebug()<<"-------------rowCount"<<building.data()->m_childrens.count()<<parent; return building.data()->m_childrens.count(); } int BuildingTreeModel::columnCount(const QModelIndex &parent) const { return 1; } QHash<int, QByteArray> BuildingTreeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; roles[nameRole] = "name"; roles[commentRole] = "comment"; return roles; } QVariant BuildingTreeModel::data(const QModelIndex &index, int role) const { qDebug()<<"-------------data"; QSharedPointer<BuildingForMap> building = getBuildingOnIndex(index); if (role== BuildingTreeModel::idRole) { return QVariant::fromValue(building.data()->m_id); } else if (role== BuildingTreeModel::nameRole) { return QVariant::fromValue(building.data()->m_name); } else if (role== BuildingTreeModel::commentRole) { return QVariant::fromValue(building.data()->m_comment); } return QVariant(); } void BuildingTreeModel::setBuilding(QSharedPointer<BuildingForMap> building) { m_building = building; m_buildingForView = building; } QVector<int> BuildingTreeModel::getDeepIndex(const QModelIndex &index) const { QVector<int> deep; if (index.isValid()) { qDebug()<<"index"<<index; if (index.parent() == QModelIndex()) { deep.append(index.row()); deep += getDeepIndex(index.parent()); } } return deep; } QSharedPointer<BuildingForMap> BuildingTreeModel::getBuildingOnIndex(const QModelIndex &index) const { QSharedPointer<BuildingForMap> building = m_building; QVector<int> deep = getDeepIndex(index); qDebug()<<"deep"<<deep<<deep.count(); qDebug()<<"building"<<building.data()->m_name; for (int i = deep.count()-1; i > -1; --i) { building = building.data()->m_childrens[i]; qDebug()<<"building"<<building.data()->m_name; } return building; }
-
Hi!
How I can create model for TreeView?
If I do this, then I have only one level in tree:#ifndef BUILDINGTREEMODEL_H #define BUILDINGTREEMODEL_H #include <QObject> #include <QAbstractItemModel> #include "structures.h" class BuildingTreeModel : public QAbstractListModel { Q_OBJECT public: BuildingTreeModel(QObject *parent = nullptr); BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent = nullptr); ~BuildingTreeModel(); enum MarkerRoles{idRole, nameRole, commentRole}; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; void setBuilding(QSharedPointer<BuildingForMap> building); private: QSharedPointer<BuildingForMap> m_building, m_buildingForView; private slots: QVector<int> getDeepIndex(const QModelIndex &index) const; //from childs to parents QSharedPointer<BuildingForMap> getBuildingOnIndex(const QModelIndex &index)const; }; #endif // BUILDINGTREEMODEL_H
#include "buildingtreemodel.h" BuildingTreeModel::BuildingTreeModel(QObject *parent) : QAbstractListModel(parent) { } BuildingTreeModel::BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent) : QAbstractListModel(parent) { setBuilding(building); } BuildingTreeModel::~BuildingTreeModel() { } int BuildingTreeModel::rowCount(const QModelIndex &parent) const { QSharedPointer<BuildingForMap> building = getBuildingOnIndex(parent); qDebug()<<"-------------rowCount"<<building.data()->m_childrens.count()<<parent; return building.data()->m_childrens.count(); } int BuildingTreeModel::columnCount(const QModelIndex &parent) const { return 1; } QHash<int, QByteArray> BuildingTreeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; roles[nameRole] = "name"; roles[commentRole] = "comment"; return roles; } QVariant BuildingTreeModel::data(const QModelIndex &index, int role) const { qDebug()<<"-------------data"; QSharedPointer<BuildingForMap> building = getBuildingOnIndex(index); if (role== BuildingTreeModel::idRole) { return QVariant::fromValue(building.data()->m_id); } else if (role== BuildingTreeModel::nameRole) { return QVariant::fromValue(building.data()->m_name); } else if (role== BuildingTreeModel::commentRole) { return QVariant::fromValue(building.data()->m_comment); } return QVariant(); } void BuildingTreeModel::setBuilding(QSharedPointer<BuildingForMap> building) { m_building = building; m_buildingForView = building; } QVector<int> BuildingTreeModel::getDeepIndex(const QModelIndex &index) const { QVector<int> deep; if (index.isValid()) { qDebug()<<"index"<<index; if (index.parent() == QModelIndex()) { deep.append(index.row()); deep += getDeepIndex(index.parent()); } } return deep; } QSharedPointer<BuildingForMap> BuildingTreeModel::getBuildingOnIndex(const QModelIndex &index) const { QSharedPointer<BuildingForMap> building = m_building; QVector<int> deep = getDeepIndex(index); qDebug()<<"deep"<<deep<<deep.count(); qDebug()<<"building"<<building.data()->m_name; for (int i = deep.count()-1; i > -1; --i) { building = building.data()->m_childrens[i]; qDebug()<<"building"<<building.data()->m_name; } return building; }
@Mihaill
To build a tree model you must use theparent
to create the depth hierarchy. See howgetDeepIndex()
recurses onindex.parent()
? Where when you populate with data are you doing setting the parent of child nodes?However, you are using
QAbstractListModel
. And that says:Since the model provides a more specialized interface than QAbstractItemModel, it is not suitable for use with tree views; you will need to subclass QAbstractItemModel if you want to provide a model for that purpose
!
-
Maybe you have simple example for tree model?
I use recurses fo find deep tree. Maybe you know how need dooing better?@Mihaill
Google does!qt tree model example
-> Simple Tree Model Example ?I use recurses fo find deep tree. Maybe you know how need dooing better?
No, recursion is the right way to do this. That code is right. But it relies on you having set up correct parentage so that the tree correctly implements descendants.
-
How I can find deep tree model, if I use my class for data?
It is not work for me:int TreeModel::rowCount(const QModelIndex &parent) const { TreeItem *parentItem; if (parent.column() > 0) return 0; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeItem*>(parent.internalPointer()); return parentItem->childCount(); }
-
With this code what me need dooing in index and parent?
#ifndef BUILDINGTREEMODEL_H #define BUILDINGTREEMODEL_H #include <QObject> #include <QAbstractItemModel> #include "structures.h" class BuildingTreeModel : public QAbstractItemModel { Q_OBJECT public: BuildingTreeModel(QObject *parent = nullptr); BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent = nullptr); ~BuildingTreeModel(); enum MarkerRoles{idRole, nameRole, commentRole}; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QModelIndex parent(const QModelIndex &index) const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; void setBuilding(QSharedPointer<BuildingForMap> building); private: QSharedPointer<BuildingForMap> m_building, m_buildingForView; private slots: QVector<int> getDeepIndex(const QModelIndex &index) const; //from childs to parents QSharedPointer<BuildingForMap> getBuildingOnIndex(const QModelIndex &index)const; }; #endif // BUILDINGTREEMODEL_H
#include "buildingtreemodel.h" BuildingTreeModel::BuildingTreeModel(QObject *parent) : QAbstractItemModel(parent) { } BuildingTreeModel::BuildingTreeModel(QSharedPointer<BuildingForMap> &building, QObject *parent) : QAbstractItemModel(parent) { setBuilding(building); } BuildingTreeModel::~BuildingTreeModel() { } int BuildingTreeModel::rowCount(const QModelIndex &parent) const { qDebug()<<"-------------rowCount1"; QSharedPointer<BuildingForMap> building = getBuildingOnIndex(parent); qDebug()<<"-------------rowCount2"<<building.data()->m_childrens.count()<<parent; return building.data()->m_childrens.count(); } int BuildingTreeModel::columnCount(const QModelIndex &parent) const { return 1; } QHash<int, QByteArray> BuildingTreeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; roles[nameRole] = "name"; roles[commentRole] = "comment"; return roles; } QVariant BuildingTreeModel::data(const QModelIndex &index, int role) const { qDebug()<<"-------------data"; QSharedPointer<BuildingForMap> building = getBuildingOnIndex(index); if (role== BuildingTreeModel::idRole) { return QVariant::fromValue(building.data()->m_id); } else if (role== BuildingTreeModel::nameRole) { return QVariant::fromValue(building.data()->m_name); } else if (role== BuildingTreeModel::commentRole) { return QVariant::fromValue(building.data()->m_comment); } return QVariant(); } QModelIndex BuildingTreeModel::parent(const QModelIndex &index) const { qDebug()<<"---BuildingTreeModel::parent"; return index; } QModelIndex BuildingTreeModel::index(int row, int column, const QModelIndex &parent) const { // QModelIndex index(row, column, *parent, this); // QModelIndex index() qDebug()<<"---BuildingTreeModel::index"; return parent; } void BuildingTreeModel::setBuilding(QSharedPointer<BuildingForMap> building) { m_building = building; m_buildingForView = building; } QVector<int> BuildingTreeModel::getDeepIndex(const QModelIndex &index) const { QVector<int> deep; if (index.isValid()) { qDebug()<<"index"<<index; if (index.parent() == QModelIndex()) { deep.append(index.row()); deep += getDeepIndex(index.parent()); } } return deep; } QSharedPointer<BuildingForMap> BuildingTreeModel::getBuildingOnIndex(const QModelIndex &index) const { QSharedPointer<BuildingForMap> building = m_building; QVector<int> deep = getDeepIndex(index); qDebug()<<"deep"<<deep<<deep.count(); qDebug()<<"building"<<building.data()->m_name; for (int i = deep.count()-1; i > -1; --i) { building = building.data()->m_childrens[i]; qDebug()<<"building"<<building.data()->m_name; } return building; }