3

在 Qt 中,您在 QAbstractItemModel 中有这个例程(以及其他例程)

bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());

如果未指定父级,则每次调用它时基本上都会实例化一个新的 QModelIndex 。

在 python 中,同一行的含义大不相同:每次调用时只会实例化和共享一个 QModelIndex

我不清楚的一点是 PyQt 是如何处理这种差异的。该文档似乎是从 C++ 文档自动生成的,结果默认参数实例化使用相同的语法,但含义完全不同,因此问题未得到解决。

这个问题当然会延续到 QAbstractItemModel 的 PyQt 中的自定义重新实现。你是否应该申报

 def insertRows(self, row, count, index=QtCore.QModelIndex()): 

或者

 def insertRows(self, row, count, index=None): 

如果索引为无,则实例化一个新的 QModelIndex?

4

3 回答 3

1
bool insertRows(int row, int count, 
                const QModelIndex &parent = QModelIndex());

def insertRows(self, row, count, index=QtCore.QModelIndex()): 

这两个示例都导致无效的索引实例。

什么是无效的QModelIndex

可以使用 QModelIndex 构造函数构造无效的模型索引。在引用模型中的顶级项时,无效索引通常用作父索引。

每次调用 insertRows是否都需要一个新的无效实例?

insertRows函数的情况下,该函数的基类实现什么都不做并返回 false。

引用的意思是如果你使用QAbstractItemModel你需要insertRows自己实现。这意味着您需要调用带有父参数的beginInsertRows 。

当涉及父索引时,Qt 的 C++ 端不会关心给定的实例。只要它是无效的,就意味着当前项在模型的顶层并且没有父项。

QAbstractItemModel不应该删除它自己没有创建的任何索引。在 C++ 中,父参数作为引用传递const,因此不会被beginInsertRows函数删除或更改。

如果 C++ 实例在 Python 中仍被引用时被删除,则可能发生的分段错误是我认为的最大问题。

现在在 Python 中,在函数定义中创建的参数通常有很长的生命周期,并且可能有一些我不知道的删除实例的方法,但通常你应该是安全的。

如果您担心这一点,只需每次都创建新实例。

index = index 或 QtCore.QModelIndex()

但是对于它的价值,我不记得在函数定义中创建索引实例时遇到了麻烦,而且我已经多次这样做了。

于 2013-06-21T09:41:35.707 回答
0

首先,按我的方式做的原因:

  1. 要求是调用insertRows“如果未指定父级,则每次调用它时都会实例化一个新的 QModelIndex”。
  2. Python 只为关键字参数分配一个默认值,而不是在每次调用时。

所以这是我的解决方案:

def insertRows(self, row, count, index=None):
    index = index or QtCore.QModelIndex()
    # do other stuff
于 2013-06-20T12:31:02.337 回答
0

这就是我在程序中的做法,添加了开头和结尾:

def insertRows(self, row, count, index): 
  self.beginInsertRows(index, row, count)
  """ Your stuff here



  """
  self.endInsertRows()

另请查看pyside 文档,因为它们通常比 pyqt 做得更好,并且在 LGPL 下,因此您可以将其用于业务。IIRC 它是相同的结果,但在不同的许可证下实现不同。

于 2013-06-17T19:35:13.597 回答