摘要class继承自ABC和QMainWindow

Abstract class inheriting from ABC and QMainWindow

from abc import ABC, abstractmethod
from PyQt5.QtWidgets import QMainWindow


class _ControlGUI(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

我的目标是定义一个基础 class _ControlGUI 与强制 structure/properties;然后定义多个继承自它的具体 classes,以及附加的 functionalities/properties。所有这些具体的 class 都是小型 GUI,因此继承自 QMainWindow,因此我认为最好让抽象的 class 直接继承自 QMainWindow。然而,这似乎是不可能的。

这个问题的最佳设计和解决方案是什么?我目前的想法是在没有 QMainWindow 的情况下定义抽象 class 并让所有具体 class 继承自 _ControlGUIQMainWindow.

如错误所述,您必须创建一个元class,它是所涉及的 class 的每个元class 的子class。

PyQT Widgets 的 metaclass 可能不是为与其他 metaclasses 协作而设计的 - 这将是一个运气问题。 ABC 的 metaclass,abc.ABCMeta(出于说明目的,我在下面将其称为 type(ABC))如果更适合协作继承,som,在派生 meta[= 时将其放在第一位24=] 会让你有更好的机会让事情真正发挥作用。 (即,除其他事项外,它将在其方法中使用 super() 调用,而不是对 type.<method> 的调用进行硬编码)。

获得派生元class后,只需在继承基础class上使用它即可。由于所有的例子都是一行代码,而且检查结果很有趣,所以我只是在交互环境上写了一些东西:

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 文档(以及其他图形工具包)怎么说,使用小部件的子 class 来创建您的应用程序可能是一个主要的痛苦。如果您只是实例化小部件并将它们作为普通 class 中的属性引用,仅继承与您的项目有关的内容,那么与从 QMainWindow 继承到开始。