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
|