我想创建一个派生自PyQt5QtWidget.QWidget
和abc.ABCMeta
的类。这两个类都有自己的元类作为类型,因此,根据this page和this SO question,我需要创建自己的元类,它派生自QWidget
和abc.ABCMeta
的元类,并显式地将其用作我的类的元类。你知道吗
到目前为止,我已经定义了一个QtAbcMeta
类,并将其用作我的ConcreteWidget
类的metaclass
(见下文)。你知道吗
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()
但是,当我尝试调用QtWidgets.QWidget
方法的__init__
方法来设置父级时,我得到以下TypeError:
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'
我不知道这里怎么了。QtWidgets.QWidget.__init__
的签名有什么变化吗?任何帮助都将不胜感激。你知道吗
QT类被设计成以协作的方式在现代Python代码中使用,这意味着它们在内部使用Python的
super()
,以确保所有超类中的所有正确方法都用各自的参数调用。你知道吗创建^{} 完全是为了避免使用超类名硬编码对超类
__init__
(和其他重写方法)的调用,这样您就不必担心调用顺序。你知道吗唯一的问题是,每个打算用作多类mixin的类都必须“知道”它是如何工作的,提取它使用的命名参数,并用剩余的参数再次调用
super
。 QT代码更进一步,检查其他类的所有命名参数是否都显示给它,否则它会出错。你知道吗更重要的是,由于Qt类本身使用super,这意味着抽象类中的
__init__
将被调用两次。它在这个简单的代码中不会有什么不同,但在更复杂的基类中可能会有问题。你知道吗因此,只需重写
__init__
方法,以“pythonic”的方式完成:相关问题 更多 >
编程相关推荐