Details
-
Task
-
Resolution: Duplicate
-
P3: Somewhat important
-
6.2.2
-
None
Description
When using a DragHandler I wrote something like this :
Item { id: root property bool allowRotations: true; signal translate(vector2d screenSpaceDelta); // Translation handler DragHandler{ target: null acceptedButtons: allowRotations ? Qt.MiddleButton: Qt.LeftButton property var lastTranslation: null onActiveChanged: { console.log(`onActiveChanged(${active})`) if(active) { console.log("Reset lastTranslation") lastTranslation = null } } onActiveTranslationChanged: { console.log(`Before: activeTranslation = ${activeTranslation}, lastTranslation = ${lastTranslation}`) if (lastTranslation !== null) { let delta = activeTranslation.minus(lastTranslation) root.translate(delta) } lastTranslation = activeTranslation console.log(`After: activeTranslation = ${activeTranslation}, lastTranslation = ${lastTranslation}`) } } }
This code would produce logs such as this one:
qml: onActiveChanged(true) qml: Reset lastTranslation qml: Before: activeTranslation = QVector2D(10, -2), lastTranslation = null qml: After: activeTranslation = QVector2D(10, -2), lastTranslation = null qml: Before: activeTranslation = QVector2D(11, -2), lastTranslation = QVector2D(11, -2) qml: => Listener got translate delta: QVector2D(0, 0) qml: After: activeTranslation = QVector2D(11, -2), lastTranslation = QVector2D(11, -2) qml: Before: activeTranslation = QVector2D(11, -3), lastTranslation = QVector2D(11, -3) qml: => Listener got translate delta: QVector2D(0, 0) qml: After: activeTranslation = QVector2D(11, -3), lastTranslation = QVector2D(11, -3) qml: onActiveChanged(false)
As you can see, there is something really strange going on: lastTranslation seems to be assigned... before it is assigned!
I finally came up with a possible explanation to this; does the lastTranslation property returns a pointer internally, to a single QVector3 that would be reused over time? If there exists actually only one value of QVector2D aliased by both variables this would explain the observed behaviour.
The documentation kind of hints that it might be the case, but not clearly:
The translation while the drag gesture is being performed. It is 0, 0 when the gesture begins, and increases as the event point(s) are dragged downward and to the right. After the gesture ends, it stays the same; and when the next drag gesture begins, it is reset to 0, 0 again.
It seems a reasonable assumption to me that vectors should be values, not references. Having DragHandler modify the values that it returned previously in an uncontrolled fashion when user code may have stored that value without suspecting is a very unexpected behaviour to me. Is this common practice in the Qt APIs?
If this behaviour is an exception, I suggest that is is changed in such a way that DragHandler instantiates new vectors every time, or to document this aliasing and reuse of QVector2D in the type documentation. If this is common practice, please let me know how I can learn more about the places where aliasing occurs in the API?
Attachments
Issue Links
- is duplicated by
-
QTBUG-127957 [Reg 6.5 -> 6.7] Reference/Value nature of lists is inconsistent
- Closed
- relates to
-
QTBUG-128358 Reduce unnecessary detaches and copies when handling value types and lists
- Reported