QAbstractItemModel index() 和 parent() 方法

QAbstractItemModel index() and parent() methods

需要实施 QAbstractItemModel.parent() 方法,否则会出现这个讨厌的错误:

NotImplementedError: QAbstractItemModel.parent() is abstract and must be overridden

除了.parent()之外,index()方法也需要重写或面对:

NotImplementedError: QAbstractItemModel.index() is abstract and must be overridden

问题:这两种方法的目的是什么,它们的工作方式有何不同?

稍后编辑:

.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)

.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()

从无尽的测试中我确实看到 .parent() 方法仅在顶级 QTableView 项目上调用。虽然 .index() 被所有项目调用:顶级,二级子项目,三级孙子项目等。我也确实看到 return QModelIndex 与行,列和数据变量 "linked" 到它。看起来由两种方法编辑的 QModelIndexes return 应该是同步的。

具有给定索引的模型项的 .parent() return 父项。如果项目没有父级,则 QModelIndex 被 return 编辑。在公开树数据结构的模型中使用的一个常见约定是只有第一列中的项目有子项。对于这种情况,在子类中重新实现此函数时,returned QModelIndex 的列将为 0。在子类中重新实现此函数时,请注意避免调用 QModelIndex 成员函数,例如 QModelIndex::parent(),因为属于您的模型的索引将简单地调用您的实现,从而导致无限递归。

.index() returns 项目在给定行、列和父索引指定的模型中的索引。在子类中重新实现此功能时,调用 createIndex() 以生成模型索引,其他组件可使用该索引来引用模型中的项目。

值得一提的是,这两种方法都使用了self.createIndex(row, column, dataVariable)方法。所以他们都做同样的事情:他们创建 QModelIndexes。我只是不明白为什么我们需要两种方法来做同样的事情!而且很难调试它,因为它们似乎 运行 在无限循环中....

这些方法被定义为抽象的,以强制用户在子类化时实现它们。如果不实现它们,您的模型将无法工作,因为它们对于定义模型的结构是必要的。

通常当你想创建一个分层模型时,你应该实现 index()parent() 方法。对于 table 和列表模型,在许多情况下,子类化 QAbstractListModelQAbstractTableModel 就足够了,它们具有这两种方法的默认实现。

简单来说 QAbstractItemModel.parent() returns 父 QModelIndex 来自子 QAbstractItemModel.index() 每当模型或视图需要创建一个 QModelIndex 对于特定的子项(如果父项无效,则为顶级项 QModelIndex)。