【问题标题】:Use QEnum like a Python Enum像 Python 枚举一样使用 QEnum
【发布时间】:2021-04-12 12:01:34
【问题描述】:

假设我有一个 python 枚举:

class UserState(Enum):
    OFFLINE = auto()
    ONLINE = auto()
    BUSY = auto()

我可以使用UserState.ONLINEUserState.OFFLINEUserState.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 中工作的枚举?

我已经找到了一个解决方案,我将在答案部分发布。但是,它涉及看起来不正确的嵌套元类。我认为最佳解决方案是从 QObject 和 Enum 派生的类,以具有适用于每个上下文的所有功能。

如果有人可以提供一个这样的版本,我会做出接受的答案。 否则你可以告诉我,为什么我的解决方案实际上是一个好的解决方案。

【问题讨论】:

  • 您是否尝试过在Qt bug tracker 上创建问题?他们或许能提供帮助。

标签: python python-3.x qt qml pyside2


【解决方案1】:

这是我写的一门课,它增加了我在问题中要求的支持:

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 类可以像普通的 python 枚举一样被继承:

class UserState(CustomEnum):
    OFFLINE = auto()
    ONLINE = auto()
    BUSY = auto()

现在您可以像在 QML 中一样在 python 中使用UserState。这对 python 和 QML 都是有效的:UserState.ONLINE

我的实现通过用 QObject 替换原始类,嵌套原始类来工作。然后将嵌套类的所有属性复制到外部类中,使其可以从python访问。

【讨论】:

  • 我想应该是metaclass=CustomEnumMeta
  • @musicamante 哦,是的,对不起,我在我的项目中使用了不同的名称。我编辑了答案。谢谢!
猜你喜欢
  • 2016-05-15
  • 1970-01-01
  • 2018-03-31
  • 2010-09-17
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多