Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.7.1
-
None
Description
Q_GADGET's property setters aren't called if assigned to, if that gadget is returned from a read only Q_PROPERTY.
struct A { Q_GADGET Q_PROPERTY(QString v READ v WRITE setV FINAL) QString m_v; public: QString v() const { return m_v; } void setV(QString v) { qDebug() << __FUNCTION__ << v; m_v = v; } }; class B : public QObject { Q_OBJECT QML_ELEMENT Q_PROPERTY(A a READ getA CONSTANT FINAL); Q_PROPERTY(A a2 READ getA WRITE setA NOTIFY aChanged FINAL); public: Q_INVOKABLE A getA() const { return {}; } void setA(const A &a) const { qDebug() << __FUNCTION__ << a.v(); }; signals: void aChanged(); };
In the following QML code, setV() is not called if A was retrieved using the b.a property. If the a2 property is used, it is called, but the result is not observed.
Window { visible: true B { id: b } Component.onCompleted: { let x = b.a // broken //let x = b.a2 // almost works //let x = b.getA() // works x.v = "foo" console.info(x.v) // expected output: "foo" } }
However, if the gadget is returned from a Q_INVOKABLE, it works as expected.
There is an argument to be made that Q_GADGETs are really constant, but as of Qt 6.7.1 this behavior is poorly documented at best
I would like to have at least my setters called, as they can have side effects - I use Q_GADGETs as proxy objects that only contain a handle to another C++ object, so workaround b.a2 is good enough for me now - I assume that in that case the engine creates a copy of A when assigning to v - which is then promptly discarded.
Attachments
Issue Links
- relates to
-
QTBUG-99766 QML value type write-back support is inconsistent
- Closed