QML:如何在自定义组件中触发onChanged?

时间:2015-08-14 15:29:59

标签: javascript qt qml

假设我们有以下自定义QML组件。

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!");
}


更改myComponent中的任何属性时,我希望触发onMyComponentChanged()。实现这一目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

在QML中,大多数属性都有onChanged事件。例如;

MyComponent {
   property string name: "Super"
}

即,on +属性+ Changed信号将被发出(属性的第一个字母将为大写) - 导致onNameChanged

Item {
    id: mainItem
    property MyComponent myCustomComponent: MyComponent {
       onNameChanged: mainItem.handleMyComponentChange()
    }
    function handleMyComponentChange() {
     -----
    }

    myCustomComponent.name="Duper"  // triggers handleMyComponentChange()
}

答案 1 :(得分:0)

您可以将信号myPropertyChanged连接到信号myComponentChanged,与c ++相同。 做到这一点:

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)
    }
}

编辑ddriver:

试试这个,你可以看到我在不改变属性的情况下发出信号:

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); 
}

答案 2 :(得分:0)

在这方面,QML存在一定的局限性。

由于您的属性本身是一个对象而不是一个基元,因此只有在将属性更改为分配给另一个对象时,其更改的信号才会发出,它不会反映此对象的内部更改。此外,您也无法手动发出信号,它只会在属性发生变化时自动发出。

myComponent.myProperty = 1.1 // this will not trigger onMyComponentChanged
myComponent = anotherObject // this will trigger onMyComponentChanged

由于您的组件只有一个属性且已有更改通知,因此您可以使用:

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")
}

...或

property var myComponent : MyComponent {
    myProperty: 13.37
}

Connections {
    target: myComponent
    onMyPropertyChanged: console.log("changed")
}

如果你的组件有多个属性,你应该在其中实现一个信号changed()并在每个被更改的属性上发出它,并使用该信号来反映内部更改,而不是QML属性自动生成的更改,这将是没有反映出来:

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")
}