Search code examples
pythonpython-3.xpyqt5qmlqqmlcontext

How to pass table-model data to qml?


I see some code write in c++ style, and I try to write it in python style.
I write a table model in python file, and then pass it to qml file.
But when I run my main.py file, The windows show nothing.
And my program don't show any error and I don't know what's wrong here? Can someone know the reason?

main.py

import os
from pathlib import Path
import sys

from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine

from PyQt5.QtCore import QAbstractTableModel, Qt


class TableModel(QAbstractTableModel):
    def __init__(self):
        super().__init__()

    def rowCount(self, parent):
        return 10

    def columnCount(self, parent) -> int:
        return 10

    def data(self, index, role: int):
        if index.isValid() and role == Qt.DisplayRole:
            return f"{index.row()},{index.column()}"

        return None

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty('myModel', TableModel())
    engine.load(os.fspath(Path(__file__).resolve().parent / "table.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

table.qml

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    width: 320
    height: 320
    visible: true

    TableView {
        anchors.fill: parent
        rowSpacing: 5
        columnSpacing: 5
        model: myModel
        delegate: myDele
    }

    Component {
        id: myDele
        Rectangle {
            implicitHeight: 50
            implicitWidth: 50
            width: 50
            height: 50
            color: "#abc"
            Text {
                anchors.centerIn: parent
                text: display
            }
        }
    }

}

Result
enter image description here


Solution

  • The problem is caused by memory management, it is better to assign to a variable than to pass the object directly to a method since it should be assumed that the object will be used but its memory will not be managed, unless the docs indicate.

    In this case you must save the object in a variable and then use it:

    myModel = TableModel()
    engine.rootContext().setContextProperty('myModel', myModel)