Completely blind guessing here, since I'm not familiar with PyQt C++ side, but what if:

- Chimera::_py_enum_types contained mapping not only to C++ name, but also type id
- Chimera::registerPyEnum the would insert both items into the hash, generating type id using qRegisterMetaType()  (assuming that it's possible to get hold of corresponding QMetaType instance here)
- The lookup inside Chimera::parse_py_type would extract both name and value, and use assign "metatype = QMetaType(metaTypeId)" instead of "QMetaType(QMetaType::Int)"

Alternatively, it's probably possible to not track int IDs, just do:
- QMetaType::registerType() in Chimera::registerPyEnum
- Use QMetaType::fromName(cpp_qualname) in Chimera::parse_py_type

Cheers,
Ivan

On 05/03/2024 17:49, Phil Thompson wrote:
The problem is 4.  For Qt6 PyQt has to use qMetaTypeId() to register the Qt enums.  This is done statically with inline calls.  As it's template based I don't know how to do the equivalent for dynamically created Python enums. I suspect that this is the missing step.

Phil

On 04/03/2024 15:58, Ivan Sinkarenko wrote:
Hi Phil,

Thanks for the info. Do you think this could be addressed in future
releases? My project has a frequent use of designer plugins that have
custom enum properties, so I would be interested to solve it.
Potentially I could give you some assistance?

I've tried to investigate the flow myself a bit, here's what I found:

1. When setting a new value, QMetaProperty::write() is called
2. It recognizes that it receives a new int value, and tries to
convert it to the target type
3. Target type is derived from a meta type, referenced by the meta
property, through a call "QMetaType
t(mobj->d.metaTypes[data.index(mobj)]);"
4. This target type for some reason has ID = 0 (i.e. UnknownType, as
defined by QMetaType::Type)
5. Conversion fails early, rejecting UnknownType, chained through
QMetaProperty::write() -> QVariant::convert() ->
QMetaType::canConvert()
6. QMetaProperty::write() returns early.

Thanks,
Ivan

On 01/03/2024 18:50, Phil Thompson wrote:
On 01/03/2024 17:24, Ivan Sinkarenko wrote:
Hi everybody,

I've seen there's been a lot happening with enums in PyQt6,
and I've managed to adapt to most of the problems, except one.
I cannot figure out how to make custom enums work in custom widgets
that are exposed to Qt Designer.

This is my simplified code:

----------------------------------------------------------------------
import enum
from PyQt6 import QtDesigner, QtGui, QtWidgets, QtCore

class MyWidget(QtWidgets.QWidget):

    @QtCore.pyqtEnum
    class MyEnum(enum.IntEnum):
        ONE = enum.auto()
        TWO = enum.auto()

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self._prop = MyWidget.MyEnum.TWO

    @QtCore.pyqtProperty(MyEnum)
    def prop(self):
        print(f'Getting property val {self._prop}')
        return self._prop

    @prop.setter
    def prop(self, new_val):
        print(f'Setting new property val {new_val}')
        self._prop = new_val

class Plugin(QtDesigner.QPyDesignerCustomWidgetPlugin):

    def name(self):
        return "MyWidget"

    def group(self):
        return "Buttons"

    def isContainer(self):
        return False

    def createWidget(self, parent):
        return MyWidget(parent)

    def icon(self):
        return QtGui.QIcon()

    def toolTip(self):
        return ""

    def whatsThis(self):
        return ""

    def includeFile(self):
        return "pyqt6_enum_designer_poc_plugin"
----------------------------------------------------------------------

I want an enum property to be displayed in the PropertySheet.
It's correctly represented by a combobox showing ONE and TWO as
available options.

TWO is correctly selected by default. However, when in Property sheet
I try to set it to ONE,
as soon as I click away from there, it's reset back to TWO. In fact,
the setter does not get called,
since the message inside is never printed. (Getter message is being printed).

Properties do work without issues, if they have built-in types, such as QColor,
or even native enums, such as Qt.Orientation.

To try this code, you can save this code to
"pyqt6_enum_designer_poc_plugin.py" and run like so:
PYQTDESIGNERPATH=$(pwd) designer

I use Qt Designer 6.6.2 and:
- PyQt6         6.6.1
- PyQt6-Qt6  6.6.2
- PyQt6-sip   13.6.0

(Also tried with PyQt6-6.5.3 PyQt6-Qt6-6.5.3, same result)

There used to be a way to make this work in PyQt5, but in PyQt6 I
tried multiple approaches without luck.
If anybody knows the correct path, that would be very appreciated!

Thanks,
Ivan

This is ringing a faint bell. I looked at it a long time ago and found that Designer was just not making the normal call to write the changed property value, maybe due to some sort of "optimisation". There may be something wrong in the way that PyQt creates the QMetaObject for the Python class but I never managed to get to the bottom of it.

Sorry for not being more helpful.

Phil