Skip to content

Data binding python example

chat GPT

import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QLabel, QLineEdit, QVBoxLayout, QWidget
from PySide2.QtCore import QObject, Signal, Slot, Property


class Person(QObject):
    def __init__(self, name='', age=0):
        super().__init__()
        self._name = name
        self._age = age

    nameChanged = Signal()
    ageChanged = Signal()

    @Property(str, notify=nameChanged)
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if self._name != value:
            self._name = value
            self.nameChanged.emit()

    @Property(int, notify=ageChanged)
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if self._age != value:
            self._age = value
            self.ageChanged.emit()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.person = Person()

        self.name_label = QLabel("Name:")
        self.name_input = QLineEdit()

        self.age_label = QLabel("Age:")
        self.age_input = QLineEdit()

        layout = QVBoxLayout()
        layout.addWidget(self.name_label)
        layout.addWidget(self.name_input)
        layout.addWidget(self.age_label)
        layout.addWidget(self.age_input)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.name_input.textChanged.connect(self.person.setName)
        self.age_input.textChanged.connect(self.updateAge)

        self.person.nameChanged.connect(self.updateName)
        self.person.ageChanged.connect(self.updateAge)

    @Slot(str)
    def updateName(self, name):
        self.name_input.setText(name)

    @Slot(str)
    def updateAge(self, age):
        self.age_input.setText(age)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    window = MainWindow()
    window.show()

    sys.exit(app.exec_())

model¶

In this example, we define a Person class as a data source with name and age properties. The Person class is derived from QObject, which enables the use of signals and properties. The nameChanged and ageChanged signals notify changes in the corresponding properties.

view¶

The MainWindow class represents the UI and handles the data binding. The name_input and age_input QLineEdit widgets are bound to the name and age properties of the Person instance. When the user enters text in the input fields, the corresponding property is updated through signals and slots.

The updateName and updateAge slots update the input fields when the properties change in the Person instance.

When you run this code, it will display a window with two input fields for name and age. The values entered in the input fields are automatically bound to the Person instance, and any changes to the Person instance will be reflected in the input fields.

Is this MVVM? no, more like MV¶

The example is not strictly an MVVM implementation. It demonstrates the concept of data binding using PySide but does not strictly follow the MVVM architectural pattern. It’s closer to the MV pattern

In the provided example, the data source (Person class) is not separated into a dedicated ViewModel component, which is a characteristic of the MVVM pattern. In MVVM, the ViewModel acts as an intermediary between the View and the Model, providing data and behaviors specifically tailored for the View.