【问题标题】:How to use Q_ENUMS in PyQt如何在 PyQt 中使用 Q_ENUMS
【发布时间】:2017-10-24 18:33:09
【问题描述】:

我正在创建一个继承自 QLabel 的自定义小部件,并且我希望在我的小部件上有一个属性来表示在呈现给用户时必须如何格式化数据。

为此,我正在尝试使用Q_ENUMS,但我并没有取得太大的成功。我可以让属性显示在 Designer 中,但保存的 UI 文件将枚举显示为 PyDMLabel::STRING,而不是我期望的 DisplayFormat::STRING。

这是我的小部件代码:

class PyDMLabel(QLabel, PyDMWidget):
    class DisplayFormat:
        DEFAULT = 0
        STRING = 1
        DECIMAL = 2
        EXPONENTIAL = 3
        HEX = 4
        BINARY = 5

    Q_ENUMS(DisplayFormat)

    """
    A QLabel with support for Channels and more from PyDM

    Parameters
    ----------
    parent : QWidget
        The parent widget for the Label
    init_channel : str, optional
        The channel to be used by the widget.
    """
    def __init__(self, parent=None, init_channel=None):
        QLabel.__init__(self, parent)
        PyDMWidget.__init__(self, init_channel=init_channel)

        self.setTextFormat(Qt.PlainText)
        self.setTextInteractionFlags(Qt.NoTextInteraction)
        self.setText("PyDMLabel")
        self._display_format_type = PyDMLabel.DisplayFormat.DEFAULT

    @pyqtProperty(DisplayFormat)
    def displayFormat(self):
        return self._display_format_type

    @displayFormat.setter
    def displayFormat(self, new_type):
        if self._display_format_type != new_type:
            self._display_format_type = new_type

处理Q_ENUMS和PyQt的正确方法是什么?

【问题讨论】:

    标签: python enums properties pyqt qt-designer


    【解决方案1】:

    为了让 Qt (Designer) 看到一个枚举,PyQt 必须将它添加到自定义类的meta-object。所以它永远不会被 Qt 称为DisplayFormat::STRING。

    在 Qt 中,在类范围内声明的枚举将其常量公开为类的成员。例如,QComboBox 类定义了一个InsertPolicy 枚举,常量可以这样引用:QComboBox::InsertAtTop。所以在这方面,Qt Designer 插件中 PyQt Q_ENUMS 的行为完全符合预期,因为 ui 文件显示了 PyDMLabel::STRING。

    但是,在 Python 代码中获得完全等效的行为需要一些额外的工作。我能想到的最接近的是:

    class DisplayFormat:
        DEFAULT = 0
        STRING = 1
        DECIMAL = 2
        EXPONENTIAL = 3
        HEX = 4
        BINARY = 5
    
    class PyDMLabel(QLabel, PyDMWidget, DisplayFormat):
        DisplayFormat = DisplayFormat
    
        Q_ENUMS(DisplayFormat)
    

    这将仍然导致 Qt Designer 使用PyDMLabel::STRING(如预期的那样)。但是 Python 代码现在可以通过以下任何方式访问常量:

    PyDMLabel.STRING
    PyDMLabel.DisplayFormat.STRING
    DisplayFormat.STRING
    

    事实上,如果您不介意失去第二个选项,您可以进一步简化:

    class DisplayFormat:
        DEFAULT = 0
        ...    
    
    class PyDMLabel(QLabel, PyDMWidget, DisplayFormat):    
        Q_ENUMS(DisplayFormat)
    

    【讨论】:

    • 谢谢@ekhumoro!有了你的建议,我就能让它发挥作用。你知道是否可以使用相同的概念创建动态枚举?
    • @hhslepicka。我不太确定。我认为 PyQt 做了一些元类骇客让Q_ENUMS 工作,这就是为什么它需要在类范围内定义。但我不知道有没有办法解决这个问题。
    • 再次感谢您。我还将尝试研究如何在与 Qt 相同的行上为一般枚举制作一些东西,如果我找到了一些东西,我会回到这里发布。
    • 我猜这也适用于实际的 Python 枚举?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多