QAbstractItemModel index () and parent () methods
You want to implement a method QAbstractItemModel.parent()
or get this nasty error:
NotImplementedError: QAbstractItemModel.parent() is abstract and must be overridden
Besides, the .parent()
method index()
must also be overridden or bounded:
NotImplementedError: QAbstractItemModel.index() is abstract and must be overridden
QUESTION . What is the purpose of both methods and what is the difference in how they work?
EDITED LATER:
Method example .parent()
:
def getNodeFromIndex(self, index):
if index.isValid():
node = index.internalPointer()
if node:
return node
return self.items
def parent(self, index):
node = self.getNodeFromIndex(index)
parentNode = node.getParent()
if parentNode == self.items:
return QtCore.QModelIndex()
return self.createIndex(parentNode.row(), 0, parentNode)
Method example .index()
:
def index(self, row, column, parentIndex):
parentNode = self.getNodeFromIndex(parentIndex)
childNode = parentNode.getChildren(row)
if childNode:
newIndex=self.createIndex(row, column, childNode)
return newIndex
else:
return QtCore.QModelIndex()
From endless testing, I can see that the method .parent()
is only called at the top level QTableView
. Although .index () is called for all elements: top-level, second-level elements, third-level grand-children, etc. I also see that both return QModelIndex
with a row, column and data variable "associated" with it. It looks like the QModelIndexes returned by both methods should be in sync.
.parent()
returns the parent of the model at the given index. If the element has no parent, an invalid is returned QModelIndex
. The general convention used in models that expose tree data structures is that only the elements in the first column have children. In this case, when QModelIndex
you reimplement this function in the subclass, the return column will be 0. If you override this function in the subclass, be careful not to call member functions QModelIndex
such as QModelIndex::parent()
since the indices belong to your model, it will just call your implementation leading to infinite recursion.
.index()
returns the index of an element in the model specified by the given column, column, and parent index. When overriding this function in a subclass, call createIndex()
to create index indices that other components can use to denote elements in your model.
It's worth mentioning that both methods use the self.createIndex(row, column, dataVariable)
. Therefore, they both do the same thing: they create QModelIndexes. I just don't understand why we need two methods to do the same! And it's hard to debug as they seem to run in an infinite loop ....
source to share
These methods are defined abstract to force the user to implement them when subclassing. Your model will not work without implementing them, because they are needed to define the structure of your model.
Usually, when you want to create a hierarchical model, you must implement the index()
and methods parent()
. For table and list models, in many cases this is sufficient for subclassing QAbstractListModel
and QAbstractTableModel
that have standard implementations of the two methods.
In simple terms, it QAbstractItemModel.parent()
returns the parent QModelIndex
of a child and QAbstractItemModel.index()
is called whenever a model or view needs to be created QModelIndex
for a specific child (or top-level element if parent is invalid QModelIndex
).
source to share