[QGIS-Developer] For an enum in pyqgis, how do I list all members and do reverse lookups?

Julien Cabieces julien.cabieces at oslandia.com
Thu Jul 3 05:38:29 PDT 2025


OK, that's interesting, I wan't ware about all those behavior difference between
QT5/6 and SIP versions.

> So if building QGIS Qt5, but with SIP6 available, I expect the result
> will be proper enum.Enums. But I have not tried.

That's my test configuration and it doesn't work. It seems we need both
Qt6 and SIP 6.

Regards,
Julien


> After getting some help from Nyall, I have boiled it down to the following:
>
> SIP 4/5: translates C++ enum into regular Python classes inheriting from 'int'. And furthermore, because of the way SIP works, __dir__ does not
> reveal the members.
>
> SIP 6: translates C++ enums into enum.Enum, which works properly with __iter__ and __members__ (and maybe __dir__ too). 
>
> Qt6 depends on SIP 6, so any version of QGIS built with Qt6 will end up having proper enum.Enum objects.
>
> When building QGIS, it will first attempt to use SIP 6, but if not available it will fall back to SIP 4/5. This happens in FindSIP.py. So if building QGIS
> Qt5, but with SIP6 available, I expect the result will be proper enum.Enums. But I have not tried.
>
> On Wed, Jul 2, 2025 at 2:19 PM Julien Cabieces <julien.cabieces at oslandia.com> wrote:
>
>  You're right, the actual code doesn't work in my environment either.
>
>  PyQt is also a wrapper of Qt made with sip, so we should get the same
>  result in sip.
>
>  QCborSimpleType is actually and exception because it fails also with
>  other Qt enums that I have tested (Qt.ItemDataRole for instance).
>
>  I don't get what happen here, the script supposedly not work like it
>  should. But it worked before, so I'm wondering what happened. Maybe SIP
>  changed things and introduced the mappingproxy thing.
>
>  I'd have to investigate a bit...
>
>  If anyone has information on this, please share :)
>
>  Regards,
>  Julien
>
>  > 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 !
>  > 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
>
>  -- 
>
>  Julien Cabieces
>  Senior Developer at Oslandia
>  julien.cabieces at oslandia.com

-- 

Julien Cabieces
Senior Developer at Oslandia
julien.cabieces at oslandia.com


More information about the QGIS-Developer mailing list