Search code examples
pythonqmlpyside6

PySide Qt dataChanged.emit() not working but LayoutChanged.emit works


from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide6.QtCore import QObject, Signal, Slot, Property, Qt,QUrl, QTimer, QAbstractListModel


class CpuLoadModel(QAbstractListModel):
    def __init__(self):
        QAbstractListModel.__init__(self)

        self.__update_timer = QTimer(self)
        self.__update_timer.setInterval(1000)
        self.__update_timer.timeout.connect(self.__update)
        self.__update_timer.start()

        self.todos = []

    def __update(self):
        self.todos.append(random.randint(0, 99))
        self.layoutChanged.emit()
        print(self.todos)
        self.dataChanged.emit(self.index,self.index,[])

    def data(self, index, role):
        if role == Qt.DisplayRole:
            text = self.todos[index.row()]
            print(f"Text: {index.row()} role : {role}")
            print("--------")
            return text

    def rowCount(self, index):
        return len(self.todos)


if __name__ == '__main__':
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    qmlRegisterType(CpuLoadModel, 'PsUtils', 1, 0, 'CpuLoadModel')
    engine.load(QUrl("main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

self.dataChange.emit method is not working at all, however self.LayoutChange.emit works but with those mistakes from qml

TypeError: Cannot read property 'width' of null

Solution

  • The layoutChanged signal must be emitted when something in the model has changed (for example it has been reordered), and dataChanged when any of the items change data but none of them is used to indicate that a row was added, in that case it must use the beginInsertRows and endInsertRows methods.

    def __update(self):
        self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
        self.todos.append(random.randint(0, 99))
        self.endInsertRows()
    

    Also change to:

    def rowCount(self, index=QModelIndex()):
        if index.isValid():
            return 0
        return len(self.todos)