Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.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
(Py)Qt:QSortFilterProxyModel使用错误模型中的父对象调用index()_Qt_Model_Pyqt_Qtreeview_Qabstractitemmodel - Fatal编程技术网

(Py)Qt:QSortFilterProxyModel使用错误模型中的父对象调用index()

(Py)Qt:QSortFilterProxyModel使用错误模型中的父对象调用index(),qt,model,pyqt,qtreeview,qabstractitemmodel,Qt,Model,Pyqt,Qtreeview,Qabstractitemmodel,我对QSortFilterProxy模型有一个奇怪的问题。我在QTreeView中执行此操作: 类CompletionViewQTreeView: def u_init__self,父项=无: 超级。初始父级 self.setModelQSortFilterProxyModel m1=完成模型 printModel 1:{}.formatm1 m1.init_数据{'test1':['1','2','3','4']} self.model.setSourceModel1 自我膨胀 m2=完成模型

我对QSortFilterProxy模型有一个奇怪的问题。我在QTreeView中执行此操作:

类CompletionViewQTreeView: def u_init__self,父项=无: 超级。初始父级 self.setModelQSortFilterProxyModel m1=完成模型 printModel 1:{}.formatm1 m1.init_数据{'test1':['1','2','3','4']} self.model.setSourceModel1 自我膨胀 m2=完成模型 printModel 2:{}.formatm2 m2.init_数据{'test':['five','six','seven','eight']} self.model.setSourceModel2 自我膨胀 这是我的CompletionModel,我无法再简化它了:

类CompletionModelQAbstrateModel: def u_init__self,父项=无: 超级。初始父级 self.\u id\u map={} self._root=CompletionItem[]*2 self.\u id\u映射[idself.\u root]=self.\u root 定义节点自身,索引: 如果index.isValid有效: 返回self.\u id\u映射[index.internalId] 其他: 返回自我 def init_dataself,数据: 对于cat,data.items中的项目: newcat=CompletionItem[cat],self.\u根 self.\u id\u map[idnewcat]=newcat self.\u root.children.appendnewcat 对于项目中的项目: newitem=CompletionItemitem,newcat self.\u id\u映射[idnewitem]=newitem newcat.children.appendnewitem def columnCountself,父项=QModelIndex: 返回self.\u root.column\u count def rowCountself,parent=QModelIndex: 如果parent.column>0: 返回0 如果不是parent.isValid: pitem=自根 其他: pitem=self.\u id\u map[parent.internalId] 返回lenpitem.children def dataself,index,role=Qt.DisplayRole: 如果index.isValid无效: 返回变量 尝试: item=self.\u id\u map[index.internalId] 除KeyError外: 返回变量 尝试: 返回QVariantitem.dataindex.column,角色 除索引器外,ValueError: 返回变量 def headerDataself,节,方向,角色=Qt.DisplayRole: 如果方向==Qt.Horizontal且角色==Qt.DisplayRole: 返回QVariantself.\u root.datasection 返回变量 def indexself,行,列,父项=QModelIndex: 如果parent.model不是None且parent.model不是self: raise ValueErrorModel不匹配:parentmodel{},self{}.formatparent.model,self
如果0刚刚想起为什么会出现这个问题

实际上,它是Python特有的方法参数,具有默认值。 Python的特殊性在于,这样的参数是静态变量。 所以第一次打电话的时候:

m1.index1,2,来自模型m1的父对象

然后再打电话:

m2.index3,4

然后,对于第二次调用,父对象将从第一次调用中的\u model\u m1 parent参数获取默认值,而不是QModelIndex,而是parent\u,作为静态变量


解决方案应该很简单-删除默认值。

重置前一个模型时,可能会在某个位置保留一些参考,因此会出现模型不匹配错误

当我尝试您的示例时,我发现在重置之间将源模型设置为“无”可以消除错误:

    self.model().setSourceModel(m1)
    ...
    self.model().setSourceModel(None) # clear the current model
    ...
    self.model().setSourceModel(m2)

在index method中:使用名为index的局部变量和方法名相同可以吗?@yshurik很好,但这不应该是个问题。同样在CompletionView的cinstructor中,当我猜您需要m2.init时,您调用m1.init_data_data@yshurik谢谢,更正了。这不是python中默认参数的工作方式。默认参数不会在每次调用时重置。在执行class语句时,默认值设置一次。因此,每当调用indexrow、column时,父参数总是QModelIndex的同一个实例。这确实是一个可行的解决方法。然而,我仍然想知道这是否是我的模型中的一个bug,我还没有发现,或者这是Qt中的一个bug,我应该打开一个bug报告。虽然纯C++测试用例很方便。我还没有详细研究过您的模型,但我看不出任何明显的理由怀疑存在bug。这些问题在PyQt中经常出现,因为每个对象都有两个方面:Python部分和Qt部分。通常,您需要以正确的顺序明确地删除内容,而不是依赖垃圾收集器来为您清理。对于项目视图中的模型尤其如此。有关更多详细信息,请参阅文档。
    self.model().setSourceModel(m1)
    ...
    self.model().setSourceModel(None) # clear the current model
    ...
    self.model().setSourceModel(m2)