File: qtenum.py

package info (click to toggle)
python-pyqtgraph 0.13.7-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,068 kB
  • sloc: python: 54,043; makefile: 129; ansic: 40; sh: 2
file content (70 lines) | stat: -rw-r--r-- 2,622 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from enum import Enum

from ...Qt import QT_LIB, QtCore
from .list import ListParameter


class QtEnumParameter(ListParameter):
    def __init__(self, enum, searchObj=QtCore.Qt, **opts):
        """
        Constructs a list of allowed enum values from the enum class provided
        `searchObj` is only needed for PyQt5 compatibility, where it must be the module holding the enum.
        For instance, if making a QtEnumParameter out of QtWidgets.QFileDialog.Option, `searchObj` would
        be QtWidgets.QFileDialog
        """
        self.enum = enum
        self.searchObj = searchObj
        opts.setdefault('name', enum.__name__)
        self.enumMap = self._getAllowedEnums(enum)

        opts.update(limits=self.formattedLimits())
        super().__init__(**opts)

    def setValue(self, value, blockSignal=None):
        if isinstance(value, str):
            value = self.enumMap[value]
        super().setValue(value, blockSignal)

    def formattedLimits(self):
        # Title-cased words without the ending substring for brevity
        mapping = self.enumMap
        shortestName = min(len(name) for name in mapping)
        names = list(mapping)
        cmpName, *names = names
        substringEnd = next(
            (
                ii + 1
                for ii in range(-1, -shortestName - 1, -1)
                if any(cmpName[ii] != curName[ii] for curName in names)
            ),
            None,
        )
        # Special case of 0: Set to None to avoid null string
        if substringEnd == 0:
            substringEnd = None
        return {kk[:substringEnd]: vv for kk, vv in self.enumMap.items()}

    def saveState(self, filter=None):
        state = super().saveState(filter)
        reverseMap = dict(zip(self.enumMap.values(), self.enumMap))
        state['value'] = reverseMap[state['value']]
        return state

    def _getAllowedEnums(self, enum):
        """Pyside provides a dict for easy evaluation"""
        if issubclass(enum, Enum):
            # PyQt6 and PySide6 (opt-in in 6.3.1) use python enums
            vals = {e.name: e for e in enum}
        elif 'PySide' in QT_LIB:
            vals = enum.values
        elif 'PyQt5' in QT_LIB:
            vals = {}
            for key in dir(self.searchObj):
                value = getattr(self.searchObj, key)
                if isinstance(value, enum):
                    vals[key] = value
        else:
            raise RuntimeError(f'Cannot find associated enum values for qt lib {QT_LIB}')
        # Remove "M<enum>" since it's not a real option
        vals.pop(f'M{enum.__name__}', None)
        return vals