-
Bug
-
Resolution: Unresolved
-
P2: Important
-
6.7.1
-
None
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.
- relates to
-
QTBUG-99766 QML value type write-back support is inconsistent
-
- Closed
-