我最近被问及pyqt继承中的一个问题,问题是:假设我有一个方法closeEvent(event)
的A类,一个继承A和QMainWindow的类B(因此有一个{{1} } 方法)。 closeEvent(event)
的解决方案顺序是什么?考虑到python文档,这将取决于继承顺序。然而,以下示例显示并非如此......是否有人可以提供帮助?
我在使用PyQt5的Windows上使用Python3.6.2。
closeEvent
答案 0 :(得分:0)
这是一个非常复杂的问题,涉及到协作多继承如何工作时Python和C ++之间的差异。所以我在这里给出的答案更多的是简要概述。我认为对于单个SO答案来说,完整的治疗可能是不可行的。
部分问题在于PyQt如何确定它应该从哪个类继承。这可以通过比较纯Python vs 类层次结构的PyQt版本的__base__
属性的值来说明:
class A: pass
class B(QMainWindow): pass
class C(A, B): pass
class D(B, A): pass
class E(QMainWindow, A): pass
class F(A, QMainWindow): pass
print('pyqt:')
print('C:', C.__base__)
print('D:', D.__base__)
print('E:', E.__base__)
print('F:', F.__base__)
class M: pass
class A: pass
class B(M): pass
class C(A, B): pass
class D(B, A): pass
class E(M, A): pass
class F(A, M): pass
print('python:')
print('C:', C.__base__)
print('D:', D.__base__)
print('E:', E.__base__)
print('F:', F.__base__)
输出:
pyqt:
C: <class '__main__.B'>
D: <class '__main__.B'>
E: <class 'PyQt5.QtWidgets.QMainWindow'>
F: <class 'PyQt5.QtWidgets.QMainWindow'>
python:
C: <class '__main__.A'>
D: <class '__main__.B'>
E: <class '__main__.M'>
F: <class '__main__.A'>
这不是错误。这里的差异完全是由于实现细节,我不打算解释(即使我可以)。 PyQt 很可能将其实现更改为与Python行为更紧密地对齐。但它反而选择妥协,而不是偏离Qt / C ++中的工作方式。我猜这个决定受到向后兼容性问题的影响,也许还有维护代码库的难易程度。可能你不得不问问PyQt的作者是否想要在这一点上得到明确的答案。
问题的另一个(更大)部分在于如何在层次结构中的某些类本身不合作时(例如,因为它们是用C ++编写的,就像Qt一样),使合作多继承工作。我认为有可能在某种程度上解决这些问题 - PyQt至少已经为类构造做了这个(见Support for Cooperative Multi-inheritance)。但是对于像Qt这样的大型库来说,这样做显然是一个更大的任务。我想总会有一些皱纹(比如你发现的那些)从未完全解决过。