[Development] Changed enum property behaviour in Qt v6.8
Phil Thompson
phil at riverbankcomputing.com
Sat Oct 5 19:16:49 CEST 2024
Hi,
Thanks for the hints - almost everything is now working (and you can
ignore my original issue about changed behaviour).
The remaining problem is that if I query the generated meta-object for
the QMetaEnum then its QMetaType is always invalid.
Looking at the QMetaObjectBuilder source I can't see where the QMetaType
passed to setMetaType() is actually used. As far as I can tell the enum
meta-types should be stored immediately after the property meta-types in
the QMetaObject data. However if you look at the relevant part of
qobjectmetaobjectbuilder.cpp (lines 1411 to 1441) you can see that no
enum meta-types are stored and a nullptr (for the QMetaObject's
meta-type) immediately follows the property meta-types. As my test case
only has one enum I think that it's seeing that nullptr as its
meta-type.
As QML defined enum properties are not allowed, would that mean that
this code wouldn't have been exercised?
Attached is a patch that fixes the problem for me - but with very little
testing.
Regards,
Phil
On 04/10/2024 15:31, Fabian Kosmale wrote:
> Hi,
>
> QMetaProperty::isEnumType's documentation probably should be adjusted
> to mention that it really is about having an enum marked with Q_ENUM,
> not about generic C++ enums.
>
> For your use-case: I suspect you need to create a dynamic meta-type
> for your enum (or rather, the QtPrivate::QMetaTypeInterface), and pass
> that to `QMetaEnumBuilder::setMetaType`. You can probably get away by
> copying most information from the QMetaTypeInterface of the underlying
> type, and just adjusting name and setting the flags.
>
> I suspect we don't have this kind of code in Qt, becuse QML currently
> doesn't allow QML defined enum properites, which would be the place
> where it's needed.
>
> Kind regards,
> Fabian Kosmale
>
>
> On 04.10.24 14:43, Phil Thompson wrote:
>> Hi Fabian,
>>
>> The change was https://codereview.qt-project.org/c/qt/qtbase/+/559265
>>
>> Reverting this change means I get the same behaviour as I get with
>> v6.7.
>>
>> I am (and always have been) using QMetaObjectBuilder and
>> addEnumerator() (the overload that takes a QByteArray argument).
>>
>> I've compared the following scenarios...
>>
>> a moc-generated meta-object where Q_ENUM is not used
>> a moc-generated meta-object where Q_ENUM is used
>> a dynamically created meta-object.
>>
>> ...for v6.7.1, v6.8.0 and v6.8.0 with the change reverted. In each
>> case I looked at the results of...
>>
>> QMetaEnum.metaType().isValid()
>> QMetaProperty.metaType().isValid()
>> QMetaProperty.isEnumType()
>>
>> The results in all cases for v6.7.1 and v6.8.0 with the change
>> reverted were identical.
>>
>> For moc-generated meta-objects...
>>
>> - the results were consistent across all versions of Qt
>> - QMetaProperty.metaType().isValid() always returned true (even if
>> QMetaEnum.metaType().isValid() returned false)
>> - QMetaProperty.isEnumType() returned true if Q_ENUM was used and
>> false if it wasn't
>>
>> For dynamically created meta-objects...
>>
>> - the results were dependent on the version of Qt
>> - QMetaProperty.metaType().isValid() always returned false
>> - QMetaProperty.isEnumType() returned true for v6.7.1 and false for
>> v6.8.0
>>
>> I was surprised by the result of QMetaProperty.isEnumType() for a
>> moc-generated meta-object without Q_ENUM. The docs suggest this should
>> be true for all enums whether or not Q_ENUM is used.
>>
>> This actually means that the v6.8 dynamic behaviour is closer to the
>> moc-generated behaviour but means it seems to be impossible to
>> dynamically create an enum property where QMetaProperty.isEnumType()
>> returns true.
>>
>> Some questions...
>>
>> Why does QMetaProperty.metaType().isValid() always return true for
>> moc-generated meta-objects and false for dynamically created
>> meta-objects?
>>
>> Is there any way to dynamically register an enum with the meta-type
>> system (so that QMetaEnum.metaType().isValid() returns true)?
>>
>> Regards,
>> Phil
>>
>> On 04/10/2024 08:02, Fabian Kosmale via Development wrote:
>>> Hi Phil,
>>>
>>> I'm not quite sure which change caused the issue, and I believe a
>>> bugreport with a reproducer might shed some light on the issue.
>>>
>>> Nevertheless, if you're already using the private QMetaObjectBuilder
>>> API, I would expect that it should work if you build the enum also
>>> dynamically via addEnumerator and then working with the returned
>>> QMetaEnumBuilder.
>>>
>>> Kind regards,
>>> Fabian
>>>
>>> On 03.10.24 17:52, Phil Thompson via Development wrote:
>>>> On 03/10/2024 16:31, Volker Hilsheimer wrote:
>>>>>> On 3 Oct 2024, at 17:07, Phil Thompson via Development
>>>>>> <development at qt-project.org> wrote:
>>>>>>
>>>>>> On 03/10/2024 15:44, Thiago Macieira wrote:
>>>>>>> On Thursday 3 October 2024 05:06:08 GMT-7 Phil Thompson via
>>>>>>> Development wrote:
>>>>>>>> Yes, that's the change - commenting out the new test fixes the
>>>>>>>> problem.
>>>>>>>> I am dynamically building the meta-object. You don't really
>>>>>>>> build an
>>>>>>>> enum, you just provide a description of it to the meta-object.
>>>>>>>> It would
>>>>>>>> be nice to be able to register an enum with the meta-type system
>>>>>>>> dynamically.
>>>>>>> Or you can set the EnumOrFlag flag in the QMetaProperty flags
>>>>>>> field to
>>>>>>> force the
>>>>>>> constructor to search.
>>>>>>
>>>>>> Sorry, can you be more specific? I can't see how to do it given
>>>>>> the private nature of the flags.
>>>>>>
>>>>>> Phil
>>>>>
>>>>>
>>>>> Hey Phil,
>>>>>
>>>>> How do you generate a dynamic meta object without using private
>>>>> APIs?
>>>>> Do you use QMetaObjectBuilder (which is private), or do you
>>>>> generate
>>>>> the tables and arrays by hand?
>>>>>
>>>>> If you use QMetaObjectBuilder, then
>>>>> QMetaPropertyBuilder::setEnumOrFlag would be the way to go.
>>>>>
>>>>> Volker
>>>>
>>>> I'm using QMetaObjectBuilder and already calling setEnumOrFlag, so
>>>> that doesn't seem to solve the problem.
>>>>
>>>> An alternative that would work for me would be to bypass the new
>>>> test if the meta-type was invalid (ie. the enum wasn't registered)
>>>> but I don't know if that would nullify the purpose of the new test.
>>>>
>>>> Phil
>>>
>>> -- Fabian Kosmale
>>> Manager R&D
>>>
>>> The Qt Company GmbH
>>> Erich-Thilo-Str. 10
>>> D-12489 Berlin
>>> fabian.kosmale at qt.io
>>> +49 1638686070
-------------- next part --------------
A non-text attachment was scrubbed...
Name: qmetaobjectbuilder.cpp.diff
Type: text/x-diff
Size: 1064 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20241005/fa40580d/attachment.diff>
More information about the Development
mailing list