[QGIS-Developer] For an enum in pyqgis, how do I list all members and do reverse lookups?
Thomas Larsen Wessel
mrvelle at gmail.com
Thu Jul 3 01:58:47 PDT 2025
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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20250703/dc688090/attachment.htm>
More information about the QGIS-Developer
mailing list