Treeview remove row
-
Tree model
TreeModel::TreeModel(Context & aContext, QObject * parent) : QAbstractItemModel(parent) , mContext(aContext) { } TreeModel::~TreeModel() { } int TreeModel::rowCount(const QModelIndex & parent) const { const auto parentItem = getItem(parent); return parentItem ? static_cast<int>(parentItem->GetChildrenSize()) : 0; } int TreeModel::columnCount(const QModelIndex & parent) const { Q_UNUSED(parent); return mContext.GetRootClass()->GetNumberOfData(); } QVariant TreeModel::data(const QModelIndex & index, int role) const { if (!index.isValid()) return QVariant(); if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); auto item = getItem(index); if (index.column() == 0) { return QString::fromStdString(item->GetName()); } else { return item->GetNumberOfStudents(); } } Qt::ItemFlags TreeModel::flags(const QModelIndex & index) const { if (!index.isValid()) return Qt::NoItemFlags; return Qt::ItemIsEditable | QAbstractItemModel::flags(index); } QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if (section == 0) { return QString("Class Name"); } else if (section == 1) { return QString("Students"); } } return QVariant(); } bool TreeModel::setData(const QModelIndex & index, const QVariant & aClassData, int role) { if (role != Qt::EditRole) return false; auto item = getItem(index); switch (index.column()) { case 0: item->SetName(aClassData.toString().toStdString()); break; case 1: item->SetNumberOfStudents(aClassData.toInt()); break; } emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole }); return true; } QModelIndex TreeModel::index(int row, int column, const QModelIndex & parent) const { if (parent.isValid() && parent.column() != 0) return QModelIndex(); auto parentItem = getItem(parent); if (!parentItem) return QModelIndex(); auto childItem = parentItem->GetChild(row); if (childItem) return createIndex(row, column, childItem); return QModelIndex(); } QModelIndex TreeModel::parent(const QModelIndex & index) const { if (!index.isValid()) return QModelIndex(); auto childItem = getItem(index); auto parentItem = childItem->GetParent(); if (parentItem == mContext.GetRootClass() || !parentItem) return QModelIndex(); return createIndex(static_cast<int>(parentItem->GetChildrenSize()), 0, parentItem); } Group * TreeModel::getItem(const QModelIndex & index) const { if (index.isValid()) { Group * item = static_cast<Group *>(index.internalPointer()); if (item) return item; } return mContext.GetRootClass(); } bool TreeModel::insertRows(int position, int rows, const QModelIndex & parent) { // insert one row at position auto parentItem = getItem(parent); if (!parentItem) return false; beginInsertRows(parent, position, position + rows - 1); parentItem->AppendChild(mContext.GenerateClassId()); endInsertRows(); return true; } bool TreeModel::removeRows(int position, int rows, const QModelIndex & parent) { auto parentItem = getItem(parent); if (!parentItem) return false; beginRemoveRows(parent, position, position + rows - 1); parentItem->RemoveChild(position); endRemoveRows(); return true; } -------------------------------------------- group.cpp -> tree nodes Group::Group(string aName, int aNumber, int aId, Group * aParent) : mName(aName) , mNumberOfStudents(aNumber) , mId(aId) , mParent(aParent) { } void Group::SetNumberOfStudents(int aNrOfStudent) { mNumberOfStudents = aNrOfStudent; } int Group::GetNumberOfStudents() { return mNumberOfStudents; } void Group::SetName(string aName) { mName = aName; } string Group::GetName() { return mName; } int Group::GetId() { return mId; } bool Group::operator==(const Group & aClass) { return mId == aClass.mId; } Group & Group::operator=(const Group & aClass) { if (this != &aClass) { this->mName = aClass.mName; this->mNumberOfStudents = aClass.mNumberOfStudents; this->mId = aClass.mId; } return *this; } Group::~Group() { } Group * Group::GetChild(int nr) { if (nr < 0 || nr >= mChildren.size()) return nullptr; return mChildren.at(nr).get(); } size_t Group::GetChildrenSize() { return mChildren.size(); } int Group::GetNumberOfData() { // class name and number of students return 2; } void Group::AppendChild(int id) { unique_ptr<Group> newClass = make_unique<Group>("name", 0, id, this); mChildren.push_back(move(newClass)); } Group * Group::GetParent() { return mParent; } void Group::RemoveChild(int pos) { if (pos < 0 || pos >= mChildren.size()) return; mChildren.erase(mChildren.begin() + pos); }
What I m doing wrong in this model? Sometimes not showing some nodes after I add more nodes, the other shows up but empty like setData was not called for them. And sometimes works just fine.
-
The first step in diagnosing a model is passing it through the model test. It usually tells you what you are doing wrong
-
Qt 5.11 or later
- Add the QtTest module to your pro file like: QT += testlib
How do I add this module in visual studio? I am not using qt creator and when i try to #include <QAbstractItemModelTester> i get this error "cannot open source file QAbstractItemModelTester "
- Add the QtTest module to your pro file like: QT += testlib
-
Thank you very much, sir. Now I need to debug the errors. I don't get it, beside I use a unique_ptr to store nodes, the model and tree nodes are the same as in the qt tree model example.. Maybe someone has encountered this errors
-
Use the debugger to see what problems are being reported.
The first screenshot is telling you that either yourindex()
orparent()
method are wrong (it checks thatmodel->parent(model->index(row,column,idx))==idx
The second screenshot is telling you your
index()
method is wrong. Passing a row, column and parent within therowCount(parent)
andcolumnCount(parent)
constraints returns an invalid index. This is likely caused by you ignoring theparent
argument inTreeModel::columnCount
-
Sir, do you have any link about qt debug in visual studio?
-
@AlexandruToma said in Treeview remove row:
Sir, do you have any link about qt debug in visual studio?
Simply debug in Visual Studio. There is no such thing as "qt debug".
-
I got the same problem as in this topic.
I changed columnCount function but the errors are still there
int TreeModel::columnCount(const QModelIndex &parent) const { return (!parent.isValid() || parent.column() == 0) ? rootItem->columnCount() : 0; }
I run tests on editable tree model in qt creator and I got the same error like in my project.
Here is the error.
// Common error test #3, the second column should NOT have the same children // as the first column in a row. // Usually the second column shouldn't have children. if (model->hasIndex(0, 1)) { QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); MODELTESTER_VERIFY(topIndex1.isValid()); if (model->rowCount(topIndex) > 0 && model->rowCount(topIndex1) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); MODELTESTER_VERIFY(childIndex.isValid()); ***QModelIndex childIndex1 = model->index(0, 0, topIndex1);*** MODELTESTER_VERIFY(childIndex1.isValid()); MODELTESTER_VERIFY(childIndex != childIndex1); } }
-
You are right, there is a bug in the example. I opened a ticket: https://bugreports.qt.io/browse/QTBUG-92178 the correct implementation should be:
int TreeModel::rowCount(const QModelIndex &parent) const { if(parent.isValid() && parent.column()>0) return 0; const TreeItem *parentItem = getItem(parent); return parentItem ? parentItem->childCount() : 0; }
-
@VRonin said in Treeview remove row:
if(parent.isValid() && parent.column()>0) return 0; const TreeItem *parentItem = getItem(parent); return parentItem ? parentItem->childCount() : 0;
All good now. Thank you very much, sir.