Type error in __init__ when deriving from two metaclasses
我想创建一个从pyqt5
到目前为止,我已经定义了一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import abc from PyQt5 import QtWidgets, QtCore class AbstractClass(metaclass=abc.ABCMeta): def __init__(self, name): self._name = name @abc.abstractmethod def myMethod(): pass class QtAbcMeta(type(QtWidgets.QWidget), type(AbstractClass)): pass class ConcreteWidget(QtWidgets.QWidget, AbstractClass, metaclass=QtAbcMeta): def __init__(self, name, parent=None): AbstractClass.__init__(self, name) QtWidgets.QWidget.__init__(self, parent=parent) # This gives a type error. def myMethod(): print("My widget does something") def main(): app = QtWidgets.QApplication([]) myWidget = ConcreteWidget('my name', parent=None) if __name__ =="__main__": main() |
但是,当我试图调用
1 2 3 4 5 6 7 8 | Traceback (most recent call last): File"main.py", line 36, in <module> main() File"main.py", line 33, in main myWidget = ConcreteWidget('my name', parent=None) File"main.py", line 24, in __init__ QtWidgets.QWidget.__init__(self, parent=parent) # This gives a type error. TypeError: __init__() missing 1 required positional argument: 'name' |
我不知道这里出了什么事。
Qt类被设计成以一种合作的方式在现代的Python代码中使用——这意味着它们在内部使用了Python的
创建
唯一的一点是,要用作多类混合的每个类都必须"知道"它是如何使用的,提取它使用的命名参数,然后用剩余的参数再次调用
更重要的是,由于qt类本身使用super,这意味着抽象类中的
所以,只需重写你的
1 2 3 4 | class ConcreteWidget(QtWidgets.QWidget, AbstractClass, metaclass=QtAbcMeta): def __init__(self, name, parent=None): super().__init__(name=name, parent=parent) |
根据文档,您必须将所有参数传递给qwidget,尽管您不需要它:
1 2 3 4 | class ConcreteWidget(QtWidgets.QWidget, AbstractClass, metaclass=QtAbcMeta): def __init__(self, name, parent=None): AbstractClass.__init__(self, name) QtWidgets.QWidget.__init__(self, name=name, parent=parent) |