Unsolved Two way property binding in QML
-
Hello.
I'm trying to define a property in the back end bind it to a qml checkbox with the goal that when the QML checkbox
checked
value is changed so will the property value. (And the other way around, when the property changes, so will thechecked
value of the checkbox)
Sadly I only managed to do it in one way. Python -> QML. When I set the value in python, the changes indeed reflect to QML. However, it doesn't work the other way around.Here is what I did:
I defined a property in Python like so:class ContextPropertyExposedClass(QObject): def __init__(): super().__init() self._checked: bool = False #getter def checked(self): return self._checked #setter def set_checked(self,checked_state): self._checked = checked_state #signal emitted when property changes @Singal def checked_changed(self): pass #slot to test if value changed on backend @Slot() def print_checked(self): print(f"Checked:{self._checked}") checked = Property(bool, fget=checked,fset=set_checked notify=checked_changed)
And then in QML:
CheckBox { text: "Is Checked" checked: ContextPropertyExposedClass.checked } Button{ onClicked:{ ContextPropertyExposedClass.print_checked() } }
When I set the value of
checked
in Python it's correctly reflected to QML. However, when I change the checkbox value in QML, and then click the button to print the values, the values in python stay the same. The setter function never gets called when the value changes in QML. I also tried to connect a slot to thechecked_changed
signal to see if it's emitted when the value is changed from QML. It did not fire.If I do:
CheckBox { text: "Is Checked" checked: ContextPropertyExposedClass.checked onCheckedChanged:{ ContextPropertyExposedClass.checked = checked } }
Then it works. But I thought the whole point of binding is that the change is reflected automatically without this additional step. Am I missing something? Is this the intended behavior?
-
Its NOT bidirectional. There are ways to bind to the values from other objects and C++, but it is about as messy as doing it from the on<value>Changed signal.
https://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html
https://doc.qt.io/qt-5/qml-qtqml-binding.html