Search code examples
pythonqtqmlpyside2

Pyside2 : Update QML TableView Model using Property


i have a python class named Manager and it's been registered like this :

backend = Manager()
engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty("backend", backend)

also in this class (Manager) i have a property named paramDs :

from PySide2.QtCore import QObject, Signal, Property, Slot

class Manager(QObject):
    processResult = Signal(bool)

    def __init__(self):
        QObject.__init__(self)
        self.ds = "loading .."

    @Slot()
    def start_processing(self):
        self.set_ds("500")

    def read_ds(self):
        return self.ds

    def set_ds(self, val):
        self.ds = val

    paramDs = Property(str, read_ds, set_ds)

also in my qml i have a Table View :

    import QtQuick 2.14
    import Qt.labs.qmlmodels 1.0
    TableView {
        id:tb
        anchors.fill: parent
        columnSpacing: 1
        rowSpacing: 1
        clip: true
    
        model: TableModel {
            TableModelColumn { display: "param_name" }
            TableModelColumn { display: "value" }
    
            rows: [
                {
                    "param_name": "Param",
                    "value": "Value"
                },
                {
                    "param_name": "number of classes",
                    "value": backend.paramDs
                }
            ]
        }
    
        delegate: Rectangle {
            implicitWidth: displayer.width + 50 <100 ? 100 :displayer.width+50
            implicitHeight: 50
            color : "#aa009688"
    
            Text {
                id:displayer
                text: display
                color : "white"
                anchors.centerIn: parent
            }
        }
    }

now some where in qml i call start_processing() slot . now paramDs should change in table view from "loading .." to "500" but it remained old "loading .." value.

why property does not update it self in qml?


Solution

  • If you are creating a binding then the property must be notifiable, that is, have an associated signal and emit it when it changes:

    class Manager(QObject):
        processResult = Signal(bool)
        df_changed = Signal()
    
        def __init__(self):
            QObject.__init__(self)
            self.ds = "loading .."
    
        @Slot()
        def start_processing(self):
            self.set_ds("500")
    
        def read_ds(self):
            return self.ds
    
        def set_ds(self, val):
            self.ds = val
            self.df_changed.emit()
    
        paramDs = Property(str, read_ds, set_ds, notify=df_changed)