[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