[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