像 Python 枚举一样使用 QEnum
Use QEnum like a Python Enum
假设我有一个 python 枚举:
class UserState(Enum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
我可以使用 UserState.ONLINE
、UserState.OFFLINE
或 UserState.BUSY
访问不同的选项。
如果我想让它成为 QEnum 以便我可以在 QML 中使用它,我需要将它包装在 QObject
中,如下所示:
class UserState(QObject):
@QEnum
class Options(Enum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
在 QML 中,我现在可以像访问 python 中的普通 python 枚举一样访问此枚举。但是,如果我想从 python 访问此枚举,我必须编写 UserState.Options.ONLINE
.
如何使用相同的语法创建可在 python 和 QML 中使用的枚举?
我找到了一个解决方案,我将在答案部分 post。然而,它涉及嵌套的 metaclasses,这看起来并不正确。我认为最佳解决方案是 class 派生自 QObject 以及 Enum 以具有每个上下文的所有功能。
如果有人可以提供类似的版本,我会将其作为可接受的答案。
否则你可以告诉我,为什么我的解决方案实际上是一个好方案。
这是我写的class,它增加了我在问题中要求的支持:
class CustomEnumMeta(type(Enum)):
def __new__(cls, name, bases, attrs):
# don't change type of base class
if name == "CustomEnum":
return super().__new__(cls, name, bases, attrs)
original_attrs = attrs.copy()
enum = super().__new__(cls, name, bases, attrs)
class WrapperMeta(type(QObject)):
def __new__(cls, wrapper_name, wrapper_bases, wrapper_attrs):
return super().__new__(cls, wrapper_name, wrapper_bases, {**original_attrs, **wrapper_attrs})
class Wrapper(QObject, metaclass=WrapperMeta):
QEnum(enum)
Wrapper.__name__ = name
return Wrapper
class CustomEnum(Enum, metaclass=CustomEnumMeta):
pass
CustomEnum class 可以像普通 python 枚举一样被继承:
class UserState(CustomEnum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
现在您可以像在 QML 中一样在 python 中使用 UserState
。这对 python 和 QML 都是有效的声明:UserState.ONLINE
我的实现工作是用 QObject 替换原来的 class,嵌套原来的 class。然后将嵌套 class 的所有属性复制到外部 class 以使它们可从 python.
访问
假设我有一个 python 枚举:
class UserState(Enum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
我可以使用 UserState.ONLINE
、UserState.OFFLINE
或 UserState.BUSY
访问不同的选项。
如果我想让它成为 QEnum 以便我可以在 QML 中使用它,我需要将它包装在 QObject
中,如下所示:
class UserState(QObject):
@QEnum
class Options(Enum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
在 QML 中,我现在可以像访问 python 中的普通 python 枚举一样访问此枚举。但是,如果我想从 python 访问此枚举,我必须编写 UserState.Options.ONLINE
.
如何使用相同的语法创建可在 python 和 QML 中使用的枚举?
我找到了一个解决方案,我将在答案部分 post。然而,它涉及嵌套的 metaclasses,这看起来并不正确。我认为最佳解决方案是 class 派生自 QObject 以及 Enum 以具有每个上下文的所有功能。
如果有人可以提供类似的版本,我会将其作为可接受的答案。 否则你可以告诉我,为什么我的解决方案实际上是一个好方案。
这是我写的class,它增加了我在问题中要求的支持:
class CustomEnumMeta(type(Enum)):
def __new__(cls, name, bases, attrs):
# don't change type of base class
if name == "CustomEnum":
return super().__new__(cls, name, bases, attrs)
original_attrs = attrs.copy()
enum = super().__new__(cls, name, bases, attrs)
class WrapperMeta(type(QObject)):
def __new__(cls, wrapper_name, wrapper_bases, wrapper_attrs):
return super().__new__(cls, wrapper_name, wrapper_bases, {**original_attrs, **wrapper_attrs})
class Wrapper(QObject, metaclass=WrapperMeta):
QEnum(enum)
Wrapper.__name__ = name
return Wrapper
class CustomEnum(Enum, metaclass=CustomEnumMeta):
pass
CustomEnum class 可以像普通 python 枚举一样被继承:
class UserState(CustomEnum):
OFFLINE = auto()
ONLINE = auto()
BUSY = auto()
现在您可以像在 QML 中一样在 python 中使用 UserState
。这对 python 和 QML 都是有效的声明:UserState.ONLINE
我的实现工作是用 QObject 替换原来的 class,嵌套原来的 class。然后将嵌套 class 的所有属性复制到外部 class 以使它们可从 python.
访问