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
-
I assume you have the Qt Visual Studio extension installed, if so right click on your project, go to qt project settings and, in the modules tab, tick Qt Test (remember to remove it once you are done)
-
-
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.
2/11