[SOLVED] property var array: [ ] doesn't trigger onChanged signal
-
With a "property var array: [ 1, 2 ], changes to the array don't trigger an onArrayChanged signal. I couldn't find anything in the documentation that explained this; does anyone know if this is supported?
import QtQuick 2.4
import QtQuick.Controls 1.3ApplicationWindow {
width: 640
height: 480
visible: trueRectangle { id: root anchors.fill: parent property var array: [ 1, 2 ] property int integer: 1 MouseArea { anchors.fill: parent onClicked: { root.array[0]++; root.integer++; console.log("array incremented to", root.array[0]); console.log("integer incremented to", root.integer); } } // this happens only on initialization, not on a mouse click onArrayChanged: console.log("array changed to", array[0]) // this happens on a mouse click onIntegerChanged: console.log("integer changed to", integer) }
}
-
The documentation says:
A list property cannot be modified in any other way. Items cannot be dynamically added to or removed from the list through JavaScript operations; any push() operations on the list only modify a copy of the list and not the actual list. (These current limitations are due to restrictions on Property Binding where lists are involved.)
You can, however, modify a copy of the list and then reassign the property to the modified value. Other options are to create an array object from within a .js JavaScript file, or implement a custom list element in C++. Here is a QML element that modifies the list in a JavaScript file:
(...)
However, note that a JavaScript list should not be used as a QML property value, as the property is not updated when the list changes. -
I'm not actually using the "list" type which is a distinct type from the "var" type. I believe the documentation you reference is from Qt 4. In Qt 5, you can add/remove/modify elements in a var array; running the code above shows the array is being modified, it's just not generating change notification.
The documentation on the "var" type does point out some limitations on change notification, but trying the workaround there didn't help: http://doc.qt.io/qt-5/qml-var.html
-
Hi!
You are right. Stumbled over this list problem some time ago and now thought things were still the same. I'm sorry! -
Ok, played around a bit with this. Looks like things are basically the same as before.
Like the current documentation (https://doc-snapshots.qt.io/qt5-5.4/qml-var.html) states, one has to reassign the property object to trigger the changed signal:import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 ApplicationWindow { title: qsTr("Hello World") width: 640 height: 480 visible: true property var car: [1,2,3] Column { Button { text: "Doesn't work" onClicked: { car[0] = 2 car[1] = 3 car[2] = 1 } } Button { text: "works" onClicked: car = [3,1,2] } Text { text: "" + car[0] + " " + car[1] + " " + car[2] } } }
-
Thanks, I tried that and it worked. It seems a bit ugly though; in real use, I'd have to make a copy of the array, modify it, and assign it back to the property.
I tried putting "arrayChanged();" after modifying array, and this actually worked (bindings to "array" were handed as expected). I've not seen that documented anywhere; is it legal?
-
Well, this myPropertyChanged - thing is documented to be universally valid and I don't think var properties are any exception to this. I use it all the time for all kinds of objects, so... :-)
-
Just for the record: How this array stuff works:
import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 ApplicationWindow { title: qsTr("Hello World") width: 640 height: 480 visible: true property var car: [1,2,3] Column { Button { text: "Doesn't work" onClicked: { car[0] = 2 car[1] = 3 car[2] = 1 } } Button { text: "Works" onClicked: car = [3,1,2] } Button { text: "Works, too" onClicked: { car[0] = 6 car[1] = 7 car[2] = 8 carChanged() } } Text { text: "" + car[0] + " " + car[1] + " " + car[2] } } }