我正在尝试使用PySide2实现QAbstractItemModel的子类。
父方法的签名是
virtual QModelIndex parent(const QModelIndex &index) const = 0
PyCharm(社区2019.3.4以及2019.2.5,以及专业2019.3(期待此签名:
import PySide2
from PySide2.QtCore import QAbstractItemModel
class MyModel(QAbstractItemModel):
def parent(self) -> PySide2.QtCore.QObject:
return super().parent()
在这个模板中,parent((没有参数,这似乎没有任何意义
当我切换到PyQt5时,自动生成的方法模板如预期:
from PyQt5.QtCore import QAbstractItemModel
class MyModel(QAbstractItemModel):
def parent(self, QModelIndex=None):
return super().parent(QModelIndex)
PySide2文档再次显示了一个正确的模式:
PySide2.QtCore.QAbstractItemModel.父(子(
Parameters child – QModelIndex Return type QModelIndex
我尝试了PySide 5.14.1和5.13.2。
这里发生了什么这是PySide2还是PyCharm中的错误?
IMHO认为在这两种情况下(PyQt5和PySide2(PyCharm linter都有一个错误。
- QAbstractItemModel是一个QObject,因此它有相同的QObject方法,而QObject有parent((方法(它是QObject之间层次结构的一部分(:
QObject *QObject::parent() const
返回指向父对象的指针。
- 此外,QAbstractItemModel处理QModelIndex之间的层次结构,因此它需要一个提供另一个QModelIndex的QModelIndex父级的父级(const QModelIndex&(方法:
QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const
返回具有给定索引的模型项的父项。如果项目没有父级,则返回无效的QModelIndex。
在公开树数据结构的模型中使用的一个常见约定是只有第一列中的项目才有子项。在这种情况下,当在子类中重新实现此函数返回QModelIndex将为0。
在子类中重新实现此函数时,要小心避免调用QModelIndex成员函数,如QModelIndex::parent((,因为属于您的模型的索引将简单地调用实现,导致无限递归。
注意:此函数可以通过元对象系统和QML。请参阅Q_INVOKABLE。
换句话说,QAbstractItemModel有两种parent()
方法(具有不同的签名(:第一种方法允许获得模型的QObject父级(因为它是QObject(,第二种方法提供模型处理的另一个QModelIndex的QModelIndex父级。
(免责声明:我不使用Pycharm或其他IDE进行自动完成(IMHO Pycharm应该提供两个自动完成,供用户选择要覆盖的方法(注意第一个是公共方法,另一个是抽象方法(。
应该注意的是,它不是PySide2或PyQt5错误,因为该库不提供自动完成,而是Pycharm。最后,我建议阅读Qt文档。
公共方法(通常(不会被重写,因此def parent(self, QModelIndex=None):
自动完成是最合适的,因为它是一个抽象方法,如果您想创建该类的实例,则必须重写它。
[两年后…]我今天遇到了同样的问题,PyCharm(2022.1(和PySide(6.2.4(都有更新的版本。
这肯定是由于PyCharm,它没有充分利用PySide的.ppy文件。
PyCharm有一个";实现/覆盖";指示符,然后单击它将转到要实现或覆盖的父方法的定义。
在我们的例子中,我最终得到了一个Python接口文件QtCore.pyi
(在我的例子中位于.../venv/Lib/site-packages/PySide6/QtCore.pyi
(
多亏了@eylanesc的回答,我看到那里生成了两个声明并不感到惊讶:
@overload
def parent(self) -> PySide6.QtCore.QObject: ...
@overload
def parent(self, child:Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex]) -> PySide6.QtCore.QModelIndex: ...
PyCharm似乎只考虑第一次出现,无论是在自动完成时,还是在检查代码时。
快速修复它非常容易:只需交换两个声明,PyCharm就会正确地自动完成(无需重新索引(,并且如果您已经手动编写了正确的签名,则不再抱怨。
我不知道如何修复它"干净";,不过,所以我不会对此做过多的阐述;这可能需要报告一个错误,但我不确定是谁报告的,因为一些搜索引擎结果表明它们是由PyCharm本身生成的,而另一些则表明它们是分布式包的一部分。