Details
-
Task
-
Resolution: Unresolved
-
P3: Somewhat important
-
6.x
Description
We need to define a behavior of REQUIRED attribute when it is mixed together with grouped and attached properties. So far, it's half-supported at best (see [1]).
- Attached properties
There are several interesting cases. The main thing about attached types is that they're opt-in: if you don't have it attached to a QML type, it does not exist for that type. Thus, we only consider cases where attached properties are explicitly set. Imagine:class MyAttached : public QObject { Q_OBJECT Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged REQUIRED) QML_ELEMENT // ... QML_ATTACHED(MyAttached) // bad style(?), but you should get the idea // ... };
Now, if we install set it in a QML type, should we get an error if required property is uninitialized?
// SomeType.qml import QtQuick Text { MyAttached.onIndexChanged: { console.log("trigger installment of an attached property"); } text: "my index is " + MyAttached.index // error: required property MyAttached.index was not initialized }
What happens if base QML type has a well-behaving attached property, but its child QML type does not?
// Base.qml import QtQuick Text { MyAttached.index: 42 text: "my index is " + MyAttached.index } // Derived.qml Base { MyAttached.onIndexChanged: { console.log("trigger installment of an attached property"); } text: "my index is not " + MyAttached.index // error or not? }
Conclusion on attached properties: we straight up reject them if there are required sub-properties there (see comments for an explanation)
- Grouped properties
Grouped properties are similar to ordinary properties really. So they must always be processed as such (even if not explicitly present).
Do we support REQUIRED attribute on the grouped property itself? What does it mean: should we set all sub-properties of group or any sub-property? (edit: yes, any binding on a group property satisfies the requirement)
What about required sub-properties of group?
class Group : public QObject { Q_OBJECT Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged REQUIRED) // is this valid? Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) // ... }; class TypeWithGroupProperty : public QObject { Q_OBJECT Q_PROPERTY(Group *group READ group /* REQUIRED */) QML_ELEMENT Group m_group; public: TypeWithGroupProperty(QObject *parent = nullptr) : QObject(parent) { } Group *group() { return &m_group; } };
// One.qml import MyModule TypeWithGroupProperty {} // error: required property group.index was not initialized -- or no error? // Another.qml import MyModule TypeWithGroupProperty { group.name: "foobar" // error: group.index was not initialized -- this is definitely an error }
Conclusion on group properties:
1. Required group is already supported (and must remain so if only to keep the existing behavior)
2. Sub-properties of group property can be marked as required and need extra code to be handled (see comments for more context/use cases)
[1]: https://codereview.qt-project.org/c/qt/qtdeclarative/+/370322
Attachments
Gerrit Reviews
For Gerrit Dashboard: QTBUG-96544 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
371158,11 | Fix required properties detection in QQmlObjectCreator | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
372704,3 | Fix required properties detection in QQmlObjectCreator | 6.2 | qt/qtdeclarative | Status: MERGED | +2 | 0 |