如何在PyQt中使用Q_ENUMS

时间:2017-10-24 18:33:09

标签: python enums properties pyqt qt-designer

我正在创建一个继承自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的正确方法是什么?

1 个答案:

答案 0 :(得分: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)

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

PyDMLabel.STRING
PyDMLabel.DisplayFormat.STRING
DisplayFormat.STRING

事实上,如果你不介意失去第二种选择,你可以进一步简化:

class DisplayFormat:
    DEFAULT = 0
    ...    

class PyDMLabel(QLabel, PyDMWidget, DisplayFormat):    
    Q_ENUMS(DisplayFormat)