Assume we have the following custom QML Components.
MyComponent.qml
//Contents for MyComponent.qml
import QtQuick 2.0
QtObject{
property real myProperty
...
}
Test.qml
import QtQuick 2.0
Item {
property var myComponent: MyComponent
onMyComponentChanged: console.log("MyComponent changed!");
}
When changing any of the properties in myComponent, I want onMyComponentChanged() to be triggered. What is the best way to acplish this?
Assume we have the following custom QML Components.
MyComponent.qml
//Contents for MyComponent.qml
import QtQuick 2.0
QtObject{
property real myProperty
...
}
Test.qml
import QtQuick 2.0
Item {
property var myComponent: MyComponent
onMyComponentChanged: console.log("MyComponent changed!");
}
When changing any of the properties in myComponent, I want onMyComponentChanged() to be triggered. What is the best way to acplish this?
Share Improve this question edited Aug 16, 2015 at 12:29 nusic asked Aug 14, 2015 at 15:29 nusicnusic 3711 gold badge3 silver badges10 bronze badges3 Answers
Reset to default 2In QML, most of the properties have onChanged events. For example;
MyComponent {
property string name: "Super"
}
i.e, on
+ Property + Changed
signal will be emitted (first letter of the property will be Upper case) - resulting in onNameChanged
Item {
id: mainItem
property MyComponent myCustomComponent: MyComponent {
onNameChanged: mainItem.handleMyComponentChange()
}
function handleMyComponentChange() {
-----
}
myCustomComponent.name="Duper" // triggers handleMyComponentChange()
}
There is kind of a limitation in QML in this regard.
Since your property is itself an object rather than a primitive, its changed signal will emit only when the property is changed to be assigned to another object, it WILL NOT reflect internal changes to this object. Also, you cannot manually emit the signal either, it will only automatically emit when the property is changed.
myComponent.myProperty = 1.1 // this will not trigger onMyComponentChanged
myComponent = anotherObject // this will trigger onMyComponentChanged
Since your ponent has only a single property and it already has a change notification, you can use that:
property var myComponent : myComp // you can omit that if you don't need it as a property
MyComponent {
id: myComp
myProperty: 13.37
onMyPropertyChanged: console.log("changed")
}
or...
property var myComponent : MyComponent {
myProperty: 13.37
}
Connections {
target: myComponent
onMyPropertyChanged: console.log("changed")
}
If your ponent has multiple properties, you should implement a signal changed()
in it and emit it on every property changed and use that signal to reflect internal changes instead of the one automatically generated by the QML property, which will not reflect them:
QtObject {
property real myProperty
property bool otherProperty
onMyPropertyChanged: changed()
onOtherPropertyChanged: changed()
signal changed()
}
...
property var myComponent : MyComponent {
myProperty: 13.37
}
Connections {
target: myComponent
onChanged: console.log("changed")
}
You can connect the signal myPropertyChanged
to the signal myComponentChanged
, the same of c++.
to do that :
import QtQuick 2.2
Item {
id:idRoot
width: 800
height: 480
property var myComponent: Item
{
id:item
property int myProperty: 13
// timer to change myProperty
Timer{
running: true
interval: 2000
repeat: true
onTriggered: item.myProperty += 1
}
}
onMyComponentChanged: console.log("MyComponent changed!");
Component.onCompleted:{
// connect signals
// info: you can connect signal to signal or signal to function
item.myPropertyChanged.connect(idRoot.myComponentChanged)
// disconnect signals
//item.myPropertyChanged.disconnect(idRoot.myComponentChanged)
}
}
Edit for ddriver:
try this, you can see that I emit the signal without changing the property:
import QtQuick 2.2
Item
{
id:idRoot
width: 800
height: 480
// when you create a property its signal myPropertyChanged()
// and its slot onMyPropertyChanged are created
// you can emit this signal when you want
property int myProperty: 13
// timer to emit myPropertyChanged()
Timer{
running: true
interval: 2000
repeat: true
onTriggered: myPropertyChanged()
}
onMyPropertyChanged: console.log("MyProperty changed!",myProperty);
}