简体   繁体   English

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

[英]QML: How to trigger onChanged in custom Component?

Assume we have the following custom QML Components. 假设我们有以下自定义QML组件。

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


When changing any of the properties in myComponent, I want onMyComponentChanged() to be triggered. 更改myComponent中的任何属性时,我希望触发onMyComponentChanged()。 What is the best way to accomplish this? 做到这一点的最佳方法是什么?

In QML, most of the properties have onChanged events. 在QML中,大多数属性具有onChanged事件。 For example; 例如;

MyComponent {
   property string name: "Super"
}

ie, on + Property + Changed signal will be emitted (first letter of the property will be Upper case) - resulting in onNameChanged 即,将发出on + Property + Changed信号(该属性的首字母为大写)-导致onNameChanged


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

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

You can connect the signal myPropertyChanged to the signal myComponentChanged , the same of c++. 您可以将信号myPropertyChanged连接到信号myComponentChanged ,与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: 编辑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); 
}

There is kind of a limitation in QML in this regard. 在这方面,QML存在某种局限性。

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 component 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 component 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: 如果您的组件具有多个属性,则应在其中实现一个信号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")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM