[QGIS-Developer] For an enum in pyqgis, how do I list all members and do reverse lookups?
Nyall Dawson
nyall.dawson at gmail.com
Wed Jul 2 15:55:30 PDT 2025
On Wed, 2 Jul 2025 at 20:43, Thomas Larsen Wessel via QGIS-Developer
<qgis-developer at lists.osgeo.org> wrote:
>
> Thanks. And that function works well for e.g. qgis.qgis.PyQt.Qt.QCborSimpleType. Which by the way has type enum.EnumType, and is defined in QGIS/share/qgis/python/qgis/PyQt/Qt.py.
>
> But Im talking about an "enum" created by SIP. Such an "enum" is a class definition, with 'int' as its only parent class. It has around 14 enum-members, e.g. "Symbology". But there is no way of getting a complete list of them. Neither with __dict__ nor dir.
>
> >>> from qgis.core import QgsMapLayer
> >>> QgsMapLayer.StyleCategory
> <class 'qgis._core.QgsMapLayer.StyleCategory'>
> >>> type(QgsMapLayer.StyleCategory)
> <class 'sip.enumtype'>
> >>> QgsMapLayer.StyleCategory.__dict__
> mappingproxy({'__module__': 'qgis._core', '__or__': <slot wrapper '__or__' of 'StyleCategory' objects>, '__ror__': <slot wrapper '__ror__' of 'StyleCategory' objects>, '__dict__': <attribute '__dict__' of 'StyleCategory' objects>, '__doc__': None, '__reduce__': <method '_pickle_enum' of 'StyleCategory' objects>, 'baseClass': <class 'qgis._core.QgsMapLayer'>})
> >>> dir(QgsMapLayer.StyleCategory)
> ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dict__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'baseClass', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'is_integer', 'numerator', 'real', 'to_bytes']
> >>> QgsMapLayer.StyleCategory.Symbology # but the members are there !
The difference is that you're using a Qt5 based build. On a qt 6 build:
QgsMapLayer.StyleCategory
<enum 'StyleCategory'>
type(QgsMapLayer.StyleCategory)
<class 'enum.EnumType'>
QgsMapLayer.StyleCategory.__dict__
mappingproxy({'_generate_next_value_': <staticmethod(<function
Enum._generate_next_value_ at 0x7b954eba74c0>)>, '__module__':
'qgis._core', '_new_member_': <built-in method __new__ of type object
at 0x7f96b1303720>, '_use_args_': True, '_member_names_':
['LayerConfiguration', 'Symbology', 'Symbology3D', 'Labeling',
'Fields', 'Forms', 'Actions', 'MapTips', 'Diagrams', 'AttributeTable',
'Rendering', 'CustomProperties', 'GeometryOptions', 'Relations',
'Temporal', 'Legend', 'Elevation', 'Notes', 'AllStyleCategories'],
'_member_map_': {'LayerConfiguration':
<StyleCategory.LayerConfiguration: 1>, 'Symbology':
<StyleCategory.Symbology: 2>, 'Symbology3D':
<StyleCategory.Symbology3D: 4>, 'Labeling': <StyleCategory.Labeling:
8>, 'Fields': <StyleCategory.Fields: 16>, 'Forms':
<StyleCategory.Forms: 32>, 'Actions': <StyleCategory.Actions: 64>,
'MapTips': <StyleCategory.MapTips: 128>, 'Diagrams':
<StyleCategory.Diagrams: 256>, 'AttributeTable':
<StyleCategory.AttributeTable: 512>, 'Rendering':
<StyleCategory.Rendering: 1024>, 'CustomProperties':
<StyleCategory.CustomProperties: 2048>, 'GeometryOptions':
<StyleCategory.GeometryOptions: 4096>, 'Relations':
<StyleCategory.Relations: 8192>, 'Temporal': <StyleCategory.Temporal:
16384>, 'Legend': <StyleCategory.Legend: 32768>, 'Elevation':
<StyleCategory.Elevation: 65536>, 'Notes': <StyleCategory.Notes:
131072>, 'AllStyleCategories': <StyleCategory.AllStyleCategories:
262143>}, '_value2member_map_': {1: <StyleCategory.LayerConfiguration:
1>, 2: <StyleCategory.Symbology: 2>, 4: <StyleCategory.Symbology3D:
4>, 8: <StyleCategory.Labeling: 8>, 16: <StyleCategory.Fields: 16>,
32: <StyleCategory.Forms: 32>, 64: <StyleCategory.Actions: 64>, 128:
<StyleCategory.MapTips: 128>, 256: <StyleCategory.Diagrams: 256>, 512:
<StyleCategory.AttributeTable: 512>, 1024: <StyleCategory.Rendering:
1024>, 2048: <StyleCategory.CustomProperties: 2048>, 4096:
<StyleCategory.GeometryOptions: 4096>, 8192: <StyleCategory.Relations:
8192>, 16384: <StyleCategory.Temporal: 16384>, 32768:
<StyleCategory.Legend: 32768>, 65536: <StyleCategory.Elevation:
65536>, 131072: <StyleCategory.Notes: 131072>, 262143:
<StyleCategory.AllStyleCategories: 262143>}, '_hashable_values_': [1,
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
32768, 65536, 131072, 262143], '_unhashable_values_': [],
'_unhashable_values_map_': {}, '_member_type_': <class 'int'>,
'_value_repr_': <slot wrapper '__repr__' of 'int' objects>, '__doc__':
None, 'LayerConfiguration': <StyleCategory.LayerConfiguration: 1>,
'Symbology': <StyleCategory.Symbology: 2>, 'Symbology3D':
<StyleCategory.Symbology3D: 4>, 'Labeling': <StyleCategory.Labeling:
8>, 'Fields': <StyleCategory.Fields: 16>, 'Forms':
<StyleCategory.Forms: 32>, 'Actions': <StyleCategory.Actions: 64>,
'MapTips': <StyleCategory.MapTips: 128>, 'Diagrams':
<StyleCategory.Diagrams: 256>, 'AttributeTable':
<StyleCategory.AttributeTable: 512>, 'Rendering':
<StyleCategory.Rendering: 1024>, 'CustomProperties':
<StyleCategory.CustomProperties: 2048>, 'GeometryOptions':
<StyleCategory.GeometryOptions: 4096>, 'Relations':
<StyleCategory.Relations: 8192>, 'Temporal': <StyleCategory.Temporal:
16384>, 'Legend': <StyleCategory.Legend: 32768>, 'Elevation':
<StyleCategory.Elevation: 65536>, 'Notes': <StyleCategory.Notes:
131072>, 'AllStyleCategories': <StyleCategory.AllStyleCategories:
262143>, '__format__': <method '__format__' of 'int' objects>,
'__new__': <function Enum.__new__ at 0x7b954eba7240>, '_missing_':
<built-in method _missing_ of EnumType object at 0x7d2682227690>,
'__sip__': <capsule object NULL at 0x7b9528f0bec0>, 'baseClass':
<class 'qgis._core.QgsMapLayer'>, '__bool__': <function <lambda> at
0x7b9520673b00>, '__eq__': <function <lambda> at 0x7b9520673ba0>,
'__and__': <function <lambda> at 0x7b9520673c40>, '__or__': <function
<lambda> at 0x7b9520673ce0>})
Nyall
> 2
>
>
> On Wed, Jul 2, 2025 at 10:00 AM Julien Cabieces <julien.cabieces at oslandia.com> wrote:
>>
>>
>> Hi,
>>
>> If you want an example, it has been done here:
>> https://github.com/qgis/QGIS/blob/cb48529abf5bd81e3c97d09809e3d56e51c943bd/scripts/pyqt5_to_pyqt6/pyqt5_to_pyqt6.py#L796
>>
>> You have to use __dict__. But I'm not sure this is a good thing to use
>> this in a plugin. The script I mention is an helper for migration from
>> qt5 to qt6, so it's kind of special.
>>
>> Regards,
>> Julien
>>
>>
>>
>> > Happy summer to all of you :)
>> >
>> > It seems in the Python bindings produced by SIP, a C++ enum is just a Python class with a certain structure. And with little/none possibility of
>> > introspection.
>> >
>> > But how can I get a list with all enum-members (e.g. Symbology, Fields) of that enum?
>> >
>> > dir(QgsMapLayer.StyleCategory) does not list them, and QgsMapLayer.StyleCategory.__members__ is undefined.
>> >
>> > Do I really have to hard code the member names into my plugin, if I want to iterate over all of them?
>> >
>> > Sincerely, Thomas
>> >
>> > _______________________________________________
>> > QGIS-Developer mailing list
>> > QGIS-Developer at lists.osgeo.org
>> > List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>> > Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>>
>> --
>>
>> Julien Cabieces
>> Senior Developer at Oslandia
>> julien.cabieces at oslandia.com
>
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
More information about the QGIS-Developer
mailing list