Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python QAbstractItemModel和QModelIndex之间的相互作用_Python_Pyside_Qabstractitemmodel_Qmodelindex - Fatal编程技术网

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相对于其父级的偏移量的任何信息。相反,这是由我们自己完成的。有没有办法让这两种功能同时发挥作用
  • 数据应如何存储在或模型索引中,以及由、为或在(不确定术语)模型索引中存储的数据与模型索引之间的区别是什么?当没有setData函数时,模型索引从何处获得返回的值?内部指针是否始终是数据?它可能是数据吗
  • ModelIndex返回的数据与模型返回的数据有什么区别?i、 e.和?为什么二传手只是虚拟的,而获得者是纯粹虚拟的。当然,API应该能够返回它存储的数据

  • 我知道我的问题链接到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的答案是正确的,但我一直在努力理解它,直到我久久地盯着它看,才发现一种模式。因此,我认为他的回答比我提问的顺序更符合逻辑

  • 不管其名称如何,QabstracteModel更好地理解为模型数据的接口。通常,模型数据的根是QAbstractItemModel对象的成员,该对象充当模型数据排序的包装器。(例如,如果数据存储在SQL数据库中,则需要另一种方法。)QAbstractItemModel也:

    • 定义数据组件之间的(层次)关系

    • 提供用于从模型中添加和删除数据行和列的函数。(这一事实是理解QModelIndex如何使用的关键。)

  • QModelIndex是很多东西,但最重要的是它包含 指向每个数据组件的内部指针,以及一些 有关当前数据组件在数据库中的位置的信息 数据层次结构(位置可以更改)。现在应该很清楚为什么文件中会说:

  • 模型索引应该立即使用,然后丢弃。你 不应依赖索引在