from abc import ABC, abstractmethod
from PyQt5.QtWidgets import QMainWindow
class _ControlGUI(QMainWindow, ABC):
pass
上面非常简单的代码引发了一个我不太清楚的错误。
TypeError:元类冲突:派生类的元类必须 是其所有基类的元类的(非严格)子类
我的目标是定义一个具有强制结构/属性的基类
_ControlGUI
;然后定义多个继承自它的具体类,并具有附加功能/属性。所有这些具体类都是小型 GUI,因此继承自 QMainWindow
,因此我认为最好让抽象类直接继承于 QMainWindow
。不过好像不太可能。
解决这个问题的最佳设计是什么?我当前的想法是定义没有
QMainWindow
的抽象类,并让所有具体类继承自 _ControlGUI
和 QMainWindow
。
正如错误所示,您必须创建一个元类,它是所涉及类的每个元类的子类。
PyQt Widgets 的元类可能并非设计为与其他元类协作 - 这将是一个运气问题。 ABC 的元类,
abc.ABCMeta
(出于说明目的,我在下面将其称为 type(ABC)
)更适合协作继承,因此,在派生元类时将其放在第一位将使您有更好的机会让事情真正发挥作用(即,除其他外,它将在其方法中使用 super()
调用,而不是硬编码对 type.<method>
的调用)。
一旦获得派生元类,只需在继承基类上使用它即可。由于所有的例子都是一行代码,而且检查结果很有趣,所以我只是在交互环境上写了一些东西:
In [1]: from PyQt5.QtWidgets import QMainWindow
In [2]: from abc import ABC, ABCMeta
In [3]: class A(QMainWindow, ABC): pass
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-86552c93e708> in <module>
----> 1 class A(QMainWindow, ABC): pass
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
In [4]: class Meta(type(ABC), type(QMainWindow)): pass
In [5]: class B(QMainWindow, ABC, metaclass=Meta): pass
顺便说一句,无论 Qt 文档(以及其他图形工具包)如何说明,使用小部件的子类来创建应用程序可能是一个很大的痛苦。如果您只是实例化小部件并将它们作为普通类中的属性引用,仅继承与您的项目相关的内容,那么与从
QMainWindow
继承开始相比,您可能会经历一个更好的旅程。