Solved Pushing to StackView with property bindings
-
Hello all,
I've got a problem when trying to push a component to a StackView and I hope someone could clarify this.
In a QML slot I push a custom component to a StackView like this:
var deviceList = Qt.createComponent("DeviceGroups.qml"); if(deviceList.status === Component.Ready) { stack.push(deviceList, { "model": modelManager.locationContent } ); }
DeviceGroups.qml is a customized ListView and the above code works as expected, hence the model is properly set. However it seems that no property bindings are created when setting the model like this. The ListView does not get updated when the model does. I confirmed that the relevant signal is being emitted and received in QML but the ListView doesn't care. To confirm this I tried the same with a simple text element which I update via a QML Timer like this:
Text { id: testText text: "This is a test" } Timer { interval: 5000 onTriggered: testText.text = testText.text + "." running: true repeat: true } [...] onClicked: { var deviceList = Qt.createComponent("Test.qml"); if(deviceList.status === Component.Ready) { stack.push(deviceList, { "text": testText.text } ); } }
Test.qml is a simple Text item so the resulting view should be updated every time the timer triggers, or am I missing something?
Thanks for any help
Tobi -
Hi! I didn't fully get what you're doing there but are you aware of the fact that you're only creating a component without actually instantiating an object from it? I guess your code should more look like this:
var component = Qt.createComponent("Button.qml"); // only a component so far if (component.status == Component.Ready) { var button = component.createObject(container); // now we have an instance button.color = "red"; }
-
@Wieland said:
Hi! I didn't fully get what you're doing there but are you aware of the fact that you're only creating a component without actually instantiating an object from it?
Thanks for the tip. But is there any difference in pushing a component to the StackView or pushing an actual instance?
To elaborate further on my problem, if I change your example a bit it might get clearer:
var component = Qt.createComponent("Button.qml"); // only a component so far if (component.status == Component.Ready) { var button = component.createObject(container); // now we have an instance button.color = somePropertyThatChangesOverTime; stack.push(button); }
My problem with this is that the color of the button that is pushed onto the StackView would not get updated.
Is this a bug or do I have to create the property binding myself (if yes, how) ?Thanks in advance!
-
@MrBolton said:
But is there any difference in pushing a component to the StackView or pushing an actual instance?
A "component" is only like a class definition in C++. See Creating a Component Dynamically.
@MrBolton said:
My problem with this is that the color of the button that is pushed onto the StackView would not get updated.
Is this a bug or do I have to create the property binding myself (if yes, how) ?It's not a bug, and yes, here you have to create the binding yourself. That's because
button.color = someThingThatChanges
is just a Javascript assignment. It only once copies the current value ofsomeThingThatChanges
tobutton.color
at exactly this point of execution. If you want to create a binding from Javascript code you can do it like this:button.color = Qt.binding(function() { return someThingThatChanges});
-
StackView::push()
acceptsItems
,Components
, andURLs
. If you want to push a QML file, the most straight-forward way is to pass the URL and letStackView
handle the rest.Passing properties to
StackView::push()
works identically withComponent::createObject()
. If you want to create a binding, you'll need to useQt.binding()
.stack.push(Qt.resolvedUrl("Button.qml"), {color: Qt.binding(function() { return foo.bar })})
We'll add a note about the property bindings to the docs.
-
@jpnurmi Thx for clarifying this! :)
-
Thank you all! As soon as I created the binding, it works like a charm!
And thanks to the explanation on component creation, it's now much less code! :)