简体   繁体   中英

How to update ListElement (QML) value field with dynamically updating property

In the below code, the property __operatingModus_season updating every 30 seconds. But in frontend, I dont see any value or changes. Please give some heads up if i am wrong.

ListModel{
    id: tileListModelBetriebsmodus
    Component.onCompleted: {
        if(__is_automatik_mode_ON){
            tileListModelBetriebsmodus.append({"tileListSource": "../../images/HausScreen/operatingModeAuto.png",
                                                  "tileListText": getFrontendText("AUTO"),
                                                  "tileListValue": __operatingModus_season
                                              })
        }else{
            tileListModelBetriebsmodus.append({"tileListSource": "../../images/HausScreen/hamburgerfinger.png",
                                                  "tileListText": getFrontendText("MANUAL"),
                                                  "tileListValue": __operatingModus_season
                                              })
        }
    }
}

This way of adding items to the ListModel doesn't make them dynamic, the values are stored on the spot.

You might be able to Create Property Bindings like this:

ListModel{
    id: tileListModelBetriebsmodus
    Component.onCompleted: {
            if(__is_automatik_mode_ON){
                tileListModelBetriebsmodus.append({"tileListSource": "../../images/HausScreen/operatingModeAuto.png",
                                                      "tileListText": getFrontendText("AUTO"),
                                                      "tileListValue": Qt.binding(function() { return __operatingModus_season })
                                                  })
            }else{
                tileListModelBetriebsmodus.append({"tileListSource": "../../images/HausScreen/hamburgerfinger.png",
                                                      "tileListText": getFrontendText("MANUAL"),
                                                      "tileListValue": Qt.binding(function() { return __operatingModus_season }
                                                  })
            }
        }
    }

Note I did not test this, if you would add a minimal working example I could have done so.

Amfasis' answer suggesting the use of Qt.binding() is on the right track, except Qt won't allow assigning a binding object directly to a ListElement. However, it allows assigning plain JS function objects. So you have to do it in two steps instead:

Step 1: Define your dynamically evaluated ListElement role as a JS function (tip: you can also use the arrow syntax to make this more readable), for example:

ListElement {
   dynamicLabel: () => config.useLabelA ? labelA : labelB
}

Step 2: Set up a binding inside your delegate between the target item and the model role:

ListView {
    delegate: Text {
        Component.onCompleted: {
            text: Qt.binding(model.dynamicLabel)
        }
    }
}

Note the need to go through Component.onCompleted as you can't do text: Qt.binding(model.dynamicLabel) directly (QML spits out an error "Invalid use of Qt.binding() in a binding declaration.").

You can't just do text: model.dynamicLabel either as that would only evaluate the JS function once at initial assignment, but not update if eg config.useLabelA changed. That's what you need the Qt.binding() wrapper for.

Building on Romain Pokrzywka's answer:

text: valuedUpdated() ? model.dynamicLabel : "" text: valuedUpdated() ? model.dynamicLabel : "" will be evaluated whenever value is updated. valuedUpdated() is a Q_PROPERTY, which returns true. Notify signal can be emitted whenever value is updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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