Die Klasse HasDataobject ist hier der Schlüssel. Es definiert einen Mix-In für Unterklassen von QGraphicsItem. Es fügt ein Attribut hinzu (
Code: Select all
dataobjectCode: Select all
update_visibility()Code: Select all
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
Code: Select all
self.setVisible(self.dataobject.is_visible())
Mein erster Gedanke war, HasDataobject zu einem zu machen Unterklasse von QGraphicsItem:
Code: Select all
class HasDataobject(QGraphicsItem, Generic[VisibleDataType])
RuntimeError: Sie können ein PySide6.QtWidgets.QGraphicsEllipseItem-Objekt in der Klasse Circle nicht zweimal initialisieren!
Also ist mein zweiter Versuch Verwenden Sie das oben definierte QGraphicsItemProtocol:
Code: Select all
class HasDataobject(Generic[VisibleDataType], QGraphicsItemProtocol)
TypeError: Es kann keine konsistente Methodenauflösungsreihenfolge (MRO) für die Basen Generic, QGraphicsItemProtocol erstellt werden
Als nächstes habe ich versucht, die beiden Basisklassen umzukehren:
Code: Select all
class HasDataobject(QGraphicsItemProtocol, Generic[VisibleDataType])
TypeError: Metaklassenkonflikt: Die Metaklasse einer abgeleiteten Klasse muss eine (nicht strenge) Unterklasse der Metaklassen aller ihrer Basen sein
Ich stecke jetzt etwas fest. Wie kann ich Typhinweise in einem obigen Code verwenden und Pyright (und mich selbst) glücklich machen?
PS: Vorschläge und Best Practices sind willkommen. Ich habe sogar mit dem Gedanken gespielt, HasDataobject zu einer echten Klasse zu machen (has-a QGraphicsItem statt is-a QGraphicsItem) anstelle eines Mix-Ins, aber Unterklassen sind wirklich vorteilhaft, da sie die Leistungsfähigkeit von Qt mit Dingen wie scene.addItem(a_circle) ermöglichen.
 Mobile version
 Mobile version