David
David

Reputation: 18281

Is it possible to connect a QML Table view to a python QAbstractModel instance?

Given a simple QML file like


TableView {
    id: myView

    topMargin: header.implicitHeight

    Text {
        id: header
        text: "A table header"
    }

    model: myModel
}

and a slightly more verbose python file

import sys

from PySide2 import QtWidgets
from PySide2.QtQuick import QQuickView
from PySide2.QtCore import Qt
from PySide2 import QtCore

class BasicModel(QtCore.QAbstractTableModel):

    def __init__(self, data):
        super(BasicModel, self).__init__()  # TODO research why the author used super this way
        self._data = data


    def headerData(self, section, orientation, role):

        if role == Qt.DisplayRole:
            return f"Test {section}"

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

        elif role == Qt.ToolTipRole:
            return f"This is a tool tip for [{index.row()}][{index.column()}]"

        else:
            pass

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

    def columnCount(self, index):
        return len(self._data[0])


def main(argv):
    app = QtWidgets.QApplication(argv)
    view = QQuickView()
    url = QtCore.QUrl("table.qml")
    view.setSource(url)

    data = [
        [4, 9, 2],
        [1, 0, 0],
        [3, 5, 0],
        [3, 3, 2],
        [7, 8, 9],
    ]

    myModel = BasicModel(data)

    # TODO somehow connect myModel python to QML Table view.

    view.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main(sys.argv)

Is it possible to take the BasicModel instance I created in the python file and bind it to the Table myView created from the QML file?

Upvotes: 0

Views: 1317

Answers (1)

eyllanesc
eyllanesc

Reputation: 243965

You just have to export the model to QML, for example using setContextProperty:

import sys

from PySide2.QtCore import Qt, QAbstractTableModel, QUrl
from PySide2.QtGui import QGuiApplication
from PySide2.QtQuick import QQuickView


class BasicModel(QAbstractTableModel):
    def __init__(self, data):
        super(BasicModel, self).__init__()
        self._data = data

    def headerData(self, section, orientation, role):

        if role == Qt.DisplayRole:
            return f"Test {section}"

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

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

    def columnCount(self, index):
        return len(self._data[0])


def main(argv):
    app = QGuiApplication(argv)

    data = [
        [4, 9, 2],
        [1, 0, 0],
        [3, 5, 0],
        [3, 3, 2],
        [7, 8, 9],
    ]

    myModel = BasicModel(data)

    view = QQuickView()
    view.setResizeMode(QQuickView.SizeRootObjectToView)
    view.resize(640, 480)

    view.rootContext().setContextProperty("myModel", myModel)

    url = QUrl("table.qml")
    view.setSource(url)
    view.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main(sys.argv)
import QtQuick 2.15

TableView {
    id: myView

    model: myModel

    delegate: Rectangle {
        implicitWidth: 100
        implicitHeight: 50
        border.width: 1

        Text {
            text: display
            anchors.centerIn: parent
        }

    }

}

In this post there is a similar example using pandas.

Upvotes: 2

Related Questions