Python QAbstractItemModel和QModelIndex之间的相互作用
下面的问题是关于Python QAbstractItemModel和QModelIndex之间的相互作用,python,pyside,qabstractitemmodel,qmodelindex,Python,Pyside,Qabstractitemmodel,Qmodelindex,下面的问题是关于qabstractemmodel和QModelIndex类的设计以及它们之间的相互作用,下面的代码示例强调了这一点: class Data: def __init__(self): self.value = 42 class Model( QAbstractItemModel ): def __init__( self ): QAbstractItemModel.__init__(self) data = Data
qabstractemmodel
和QModelIndex
类的设计以及它们之间的相互作用,下面的代码示例强调了这一点:
class Data:
def __init__(self):
self.value = 42
class Model( QAbstractItemModel ):
def __init__( self ):
QAbstractItemModel.__init__(self)
data = Data()
modelIndex = self.createIndex( 1 , 2 , data ) ### 1
self.index( 1 , 2 , QModelIndex() ) ### 2
self.setData( modelIndex , data.value ) ### 3
self.dataChanged.emit( modelIndex , modelIndex )
modelIndex.data() ###4
self.data( modelIndex ) ### 5
QModelIndex
。从我对文档的阅读来看,答案是肯定的,但它似乎不完整,因为此函数不提供有关ModelIndex相对于其父级的偏移量的任何信息。相反,这是由我们自己完成的。有没有办法让这两种功能同时发挥作用我知道我的问题链接到C++ API,而代码段在PySide。我这样做是因为这个问题跨越了两个API。考虑到您有许多与QabstracteModel和QModelIndex相关的问题,涉及到实现和其他设计问题,我将花时间逐一回答,因此我将编辑此答案,提供更多详细信息 1. QModelIndex没有父对象的信息,也没有表示的偏移量的信息,它只保留数据的行、列、指针以及它所属的模型的信息(请参阅)。因此,当您知道父对象是谁时,这就是您的任务,您必须重写模型的方法并返回该方法
def父级(自身,索引):
如果不是index.isValid():
返回QtCore.QModelIndex()
childItem=index.internalPointer()
parentItem=childItem.parentItem()
如果parentItem==self.rootItem:
返回QtCore.QModelIndex()
返回self.createIndex(…,…,parentItem)
因此,在QModelIndex的方法中,这个函数通过模型获取父对象(请参见):def parent(self):返回self.model.parent(self)
关于和方法之间的关系,第二个方法由第一个方法调用,但也必须与您的数据结构有关系。通用实现是:
def索引(self、row、column、parent):
如果不是self.hasIndex(行、列、父项):
返回QtCore.QModelIndex()
parentItem=None
如果不是parent.isValid():
parentItem=self.rootItem
其他:
parentItem=parent.internalPointer()
childItem=parentItem.child(…)
如果childItem不是None:
返回self.createIndex(行、列、子项)
返回QtCore.QModelIndex()
在createIndex()的情况下,只创建一个包含行、列、模型和指向childItem的指针的QModelIndex,该构造函数不在文档中,因为它是一个私有构造函数(请参阅)
2.
internalPointer是一个存储数据的内存位置的变量,也就是说,QModelIndex没有数据,但知道数据在哪里,因此数据必须单独存储,因此,当使用模型的方法获取数据时,必须获取internalPointer(),它返回存储信息的项,并根据该角色获取数据
def数据(self,index,role=QtCore.Qt.DisplayRole):
如果不是index.isValid():
返回
item=index.internalPointer()
value=item.data(…,role)#类似item.value
返回值
3.
QModelIndex的方法使用模型的方法(请参阅),因此在概念上它们是相同的,例如:def data(self,role):返回self.model.data(self,role)
并非每个模型都可编辑,例如QStringListModel不可编辑,因此不必覆盖该方法,因此Qt默认情况下使模型不可编辑,即它们不执行任何操作并返回false(请参见),因此这意味着它必须是虚拟的,即,仅当未重写此方法时,才会对其进行修改,如果不执行此操作,则将调用父方法,也就是说,它不会执行任何操作。与该方法不同,因为每个模型都必须返回信息,所以当该类从QabstracteModel继承时,开发人员必须强制覆盖该类,因此该类被声明为纯虚拟类。我建议你阅读,以便更详细地了解不同之处:虽然@eyllanesc的答案是正确的,但我一直在努力理解它,直到我久久地盯着它看,才发现一种模式。因此,我认为他的回答比我提问的顺序更符合逻辑
- 定义数据组件之间的(层次)关系
- 提供用于从模型中添加和删除数据行和列的函数。(这一事实是理解QModelIndex如何使用的关键。)