<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    
    Completely blind guessing here, since I'm not familiar with PyQt C++
    side, but what if:<br>
    <br>
    - <span style=""><a class="moz-txt-link-freetext" href="Chimera::_py_enum_types">Chimera::_py_enum_types</a></span> contained mapping
    not only to C++ name, but also type id<br>
    - <span style=""><a class="moz-txt-link-freetext" href="Chimera::registerPyEnum">Chimera::registerPyEnum</a></span> 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)<br>
    - The lookup inside <span style=""><a class="moz-txt-link-freetext" href="Chimera::parse_py_type">Chimera::parse_py_type</a></span>
    would extract both name and value, and use assign "metatype =
    QMetaType(metaTypeId)" instead of "QMetaType(<span style=""><a class="moz-txt-link-freetext" href="QMetaType::Int">QMetaType::Int</a></span>)"<br>
    <br>
    Alternatively, it's probably possible to not track int IDs, just do:
    <br>
    - <a href="https://doc.qt.io/qt-6/qmetatype.html#registerType" moz-do-not-send="true">QMetaType::registerType()</a> in <span style=""><a class="moz-txt-link-freetext" href="Chimera::registerPyEnum">Chimera::registerPyEnum</a></span><br>
    - Use <span style=""><a class="moz-txt-link-freetext" href="QMetaType::fromName(cpp_qualname)">QMetaType::fromName(cpp_qualname)</a></span> in <span style=""><a class="moz-txt-link-freetext" href="Chimera::parse_py_type">Chimera::parse_py_type</a></span><br>
    <br>
    Cheers,<br>
    Ivan<br>
    <br>
    <div class="moz-cite-prefix">On 05/03/2024 17:49, Phil Thompson
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:4dd7c10738dcf84e5e30a406d29424d5@riverbankcomputing.com">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. <br>
      <br>
      Phil <br>
      <br>
      On 04/03/2024 15:58, Ivan Sinkarenko wrote: <br>
      <blockquote type="cite">Hi Phil, <br>
        <br>
        Thanks for the info. Do you think this could be addressed in
        future <br>
        releases? My project has a frequent use of designer plugins that
        have <br>
        custom enum properties, so I would be interested to solve it. <br>
        Potentially I could give you some assistance? <br>
        <br>
        I've tried to investigate the flow myself a bit, here's what I
        found: <br>
        <br>
        1. When setting a new value, <a class="moz-txt-link-freetext" href="QMetaProperty::write()" moz-do-not-send="true">QMetaProperty::write()</a>
        is called <br>
        2. It recognizes that it receives a new int value, and tries to
        <br>
        convert it to the target type <br>
        3. Target type is derived from a meta type, referenced by the
        meta <br>
        property, through a call "QMetaType <br>
        t(mobj->d.metaTypes[data.index(mobj)]);" <br>
        4. This target type for some reason has ID = 0 (i.e.
        UnknownType, as <br>
        defined by <a class="moz-txt-link-freetext" href="QMetaType::Type" moz-do-not-send="true">QMetaType::Type</a>)
        <br>
        5. Conversion fails early, rejecting UnknownType, chained
        through <br>
        <a class="moz-txt-link-freetext" href="QMetaProperty::write()" moz-do-not-send="true">QMetaProperty::write()</a> -> <a class="moz-txt-link-freetext" href="QVariant::convert()" moz-do-not-send="true">QVariant::convert()</a> -> <br>
        <a class="moz-txt-link-freetext" href="QMetaType::canConvert()" moz-do-not-send="true">QMetaType::canConvert()</a> <br>
        6. <a class="moz-txt-link-freetext" href="QMetaProperty::write()" moz-do-not-send="true">QMetaProperty::write()</a>
        returns early. <br>
        <br>
        Thanks, <br>
        Ivan <br>
        <br>
        On 01/03/2024 18:50, Phil Thompson wrote: <br>
        <blockquote type="cite">On 01/03/2024 17:24, Ivan Sinkarenko
          wrote: <br>
          <blockquote type="cite">Hi everybody, <br>
            <br>
            I've seen there's been a lot happening with enums in PyQt6,
            <br>
            and I've managed to adapt to most of the problems, except
            one. <br>
            I cannot figure out how to make custom enums work in custom
            widgets <br>
            that are exposed to Qt Designer. <br>
            <br>
            This is my simplified code: <br>
            <br>
---------------------------------------------------------------------- <br>
            import enum <br>
            from PyQt6 import QtDesigner, QtGui, QtWidgets, QtCore <br>
            <br>
            class MyWidget(QtWidgets.QWidget): <br>
            <br>
                @QtCore.pyqtEnum <br>
                class MyEnum(enum.IntEnum): <br>
                    ONE = enum.auto() <br>
                    TWO = enum.auto() <br>
            <br>
                def __init__(self, *args, **kwargs) -> None: <br>
                    super().__init__(*args, **kwargs) <br>
                    self._prop = MyWidget.MyEnum.TWO <br>
            <br>
                @QtCore.pyqtProperty(MyEnum) <br>
                def prop(self): <br>
                    print(f'Getting property val {self._prop}') <br>
                    return self._prop <br>
            <br>
                @prop.setter <br>
                def prop(self, new_val): <br>
                    print(f'Setting new property val {new_val}') <br>
                    self._prop = new_val <br>
            <br>
            class Plugin(QtDesigner.QPyDesignerCustomWidgetPlugin): <br>
            <br>
                def name(self): <br>
                    return "MyWidget" <br>
            <br>
                def group(self): <br>
                    return "Buttons" <br>
            <br>
                def isContainer(self): <br>
                    return False <br>
            <br>
                def createWidget(self, parent): <br>
                    return MyWidget(parent) <br>
            <br>
                def icon(self): <br>
                    return QtGui.QIcon() <br>
            <br>
                def toolTip(self): <br>
                    return "" <br>
            <br>
                def whatsThis(self): <br>
                    return "" <br>
            <br>
                def includeFile(self): <br>
                    return "pyqt6_enum_designer_poc_plugin" <br>
---------------------------------------------------------------------- <br>
            <br>
            I want an enum property to be displayed in the
            PropertySheet. <br>
            It's correctly represented by a combobox showing ONE and TWO
            as <br>
            available options. <br>
            <br>
            TWO is correctly selected by default. However, when in
            Property sheet <br>
            I try to set it to ONE, <br>
            as soon as I click away from there, it's reset back to TWO.
            In fact, <br>
            the setter does not get called, <br>
            since the message inside is never printed. (Getter message
            is being printed). <br>
            <br>
            Properties do work without issues, if they have built-in
            types, such as QColor, <br>
            or even native enums, such as Qt.Orientation. <br>
            <br>
            To try this code, you can save this code to <br>
            "pyqt6_enum_designer_poc_plugin.py" and run like so: <br>
            PYQTDESIGNERPATH=$(pwd) designer <br>
            <br>
            I use Qt Designer 6.6.2 and: <br>
            - PyQt6         6.6.1 <br>
            - PyQt6-Qt6  6.6.2 <br>
            - PyQt6-sip   13.6.0 <br>
            <br>
            (Also tried with PyQt6-6.5.3 PyQt6-Qt6-6.5.3, same result) <br>
            <br>
            There used to be a way to make this work in PyQt5, but in
            PyQt6 I <br>
            tried multiple approaches without luck. <br>
            If anybody knows the correct path, that would be very
            appreciated! <br>
            <br>
            Thanks, <br>
            Ivan <br>
          </blockquote>
          <br>
          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. <br>
          <br>
          Sorry for not being more helpful. <br>
          <br>
          Phil <br>
        </blockquote>
      </blockquote>
    </blockquote>
    <br>
    <br>
    <br>
  </body>
</html>