It is required to implement QAbstractItemModel.parent()
method or else get this nasty error:
NotImplementedError: QAbstractItemModel.parent() is abstract and must be overridden
Aside from .parent()
the index()
method also needs to be overridden or face:
NotImplementedError: QAbstractItemModel.index() is abstract and must be overridden
QUESTION: What are the purpose of both methods and what is the difference in the way they work?
EDITED LATER:
Example of .parent()
method:
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)
Example on .index()
method:
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 do see that .parent()
method is called only on top level QTableView
items. While .index() is called for all the items: top-level, second-level children items, third-level grand-children items and etc. I also do see that both return QModelIndex
with row, column and data variable "linked" to it. It looks like the QModelIndexes returned by both methods should be in sync.
The .parent()
returns parent of model item with given index. If item has no parent, an invalid QModelIndex
is returned. A common convention used in models that expose tree data structures is that only items in first column have children. For that case, when reimplementing this function in a subclass the column of the returned QModelIndex
would be 0. When reimplementing this function in a subclass, be careful to avoid calling QModelIndex
member functions, such as QModelIndex::parent()
, since indexes belonging to your model will simply call your implementation leading to infinite recursion.
The .index()
returns the index of the item in the model specified by the given row, column and parent index. When reimplementing this function in a subclass, call createIndex()
to generate model indexes that other components can use to refer to items in your model.
It is worth to mention that both methods use self.createIndex(row, column, dataVariable)
method. So they both do the same thing: they create QModelIndexes. I just don't understand why we need two methods to do the same thing! And it is hard to debug it since it seems they run in infinite loop....