Класс HasDataobject играет здесь ключевую роль. Он определяет примесь для подклассов QGraphicsItem. Он добавляет атрибут (
Код: Выделить всё
dataobjectКод: Выделить всё
update_visibility()Код: Выделить всё
from typing import TypeVar, Generic, Protocol
from PySide6.QtWidgets import QGraphicsItem, QGraphicsEllipseItem
# QGraphicsEllipseItem is a subclass of QGraphicsItem
### Data objects ###
class VisibleData:
def is_visible(self) -> bool:
return True
class MyNode(VisibleData):
pass
VisibleDataType = TypeVar('VisibleDataType', bound=VisibleData)
### Visual objects (using PySide6) ###
class QGraphicsItemProtocol(Protocol):
"""Define the methods of QGraphicsItem that HasDataobject uses."""
def setVisible(self, visible: bool, /):
...
class HasDataobject(Generic[VisibleDataType]):
"""Mix-in class. Adds an update_visibility() method, and
a dataobject attribute. The dataobject must have a
is_visible() method, as defined in VisibleData.
Any subclass of HasDataobject must also be a subclass of
QGraphicsItem, which defines setVisible()."""
dataobject: VisibleDataType
def update_visibility(self):
self.setVisible(self.dataobject.is_visible())
class Circle(QGraphicsEllipseItem, HasDataobject[MyNode]):
def __init__(self):
super().__init__()
pass
Код: Выделить всё
self.setVisible(self.dataobject.is_visible())
Моя первоначальная мысль заключалась в том, чтобы сделать HasDataobject подклассом QGraphicsItem:
Код: Выделить всё
class HasDataobject(QGraphicsItem, Generic[VisibleDataType])
RuntimeError: невозможно инициализировать объект PySide6.QtWidgets.QGraphicsEllipseItem в классе Circle дважды!
Поэтому моя вторая попытка — использовать метод QGraphicsItemProtocol определяется выше:
Код: Выделить всё
class HasDataobject(Generic[VisibleDataType], QGraphicsItemProtocol)
TypeError: невозможно создать согласованный порядок разрешения методов (MRO) для баз Generic, QGraphicsItemProtocol
Поэтому затем я попытался поменять местами два базовых класса:
Код: Выделить всё
class HasDataobject(QGraphicsItemProtocol, Generic[VisibleDataType])
TypeError: конфликт метаклассов: метакласс производного класса должен быть (нестрогим) подклассом метаклассов всех его баз.
Я немного застрял. Как я могу использовать подсказки типов в этом коде и осчастливить Пайрайта (и себя)?
PS: Любые предложения и лучшие практики приветствуются. Я даже подумывал сделать HasDataobject настоящим классом (has-a QGraphicsItem вместо is-a QGraphicsItem) вместо примеси, но создание подклассов действительно полезно, поскольку оно позволяет использовать возможности Qt с такими вещами, как Scene.addItem(a_circle).
Подробнее здесь: https://stackoverflow.com/questions/797 ... typeerrors
Мобильная версия