Controls appear to break bindings when interacted with
-
For example, a basic checkbox:
CheckBox { checked: model.value onClicked: model.maybe_change_value_maybe_not_depends_on_complex_business_logic(); }What I expect this means is
checkedis now bound tomodel.value, and must never deviate frommodel.value. Unfortunately it can. Note my verbosely named function: sometimes the value is changed, but when it isnt the property cannot notify and thus the checkbox becomes desynced. In this state,checkedis observably different frommodel.value!! I cannot just dochecked = model.valuein the slot foronClickedbecause that breaks the binding completely. I instead have to do janky stuff like this:CheckBox { property int evil_hacky_hack: 0 checked: evil_hacky_hack, model.value onClicked: { model.maybe_change_value_maybe_not_depends_on_complex_business_logic(); ++evil_hacky_hack // Force a re-evaluate } }Note that I've observed this happening with other stateful control types, like
TextField(witheditingFinished). This leads me to believe that it's a conscious design choice instead of a bug.So I guess my question here: Am I missing a better supported, more scalable way to do this that's applicable to all controls? Is there a way to make
CheckBox(and Qml's controls in general) a pure view for my model data without significant skulduggery? It's infeasible (and inadvisable, imo) to change my model to notify when a change doesn't happen.Qt 5.9 if it matters; I'm not sure what to search for in changelogs to check for fixes (or how to try this in Qt6). Also my first post here, lmk if this belongs elsewhere.
-
I dont know if this helps you now, since noone has responded... but the way i solve this (and i've had to do it on multiple ui elements) is as follows:
- Create custom qml type where the base item is the same as the original (CheckBox in this case)
- Add
property var checkedBinding - Add
Component.onCompleted:{if(typeof checkedBinding==='function' checked=Qt.binding(checkedBinding)} - Add
onClicked:{if(typeof checkedBinding==='function' checked=Qt.binding(checkedBinding)}
Then when using the component, instead of setting
checked:model.valueyou can usecheckedBinding:function(){return model.value}This is really annoying behavior and i wish qt would fix it. it's not as bad in this simple case, but it can cause a lot of issues when you are doing multiple components put together with custom behavior. The example that bothers me the most is making a DoubleSpinbox item , since the act of changing the binding itself to handle doubles automatically conflicts with using the element itself (even ignoring outside bindings) and will thus automatically unbind itself from the original implementation of the double spin box.