是否可以将 QML Table 视图连接到 python QAbstractModel 实例?

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

给定一个简单的 QML 文件,例如


TableView {
    id: myView

    topMargin: header.implicitHeight

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

    model: myModel
}

还有一个稍微冗长的 python 文件

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)

是否可以将我在 python 文件中创建的 BasicModel 实例绑定到从 QML 文件创建的 Table myView

您只需将模型导出到 QML,例如使用 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
        }

    }

}

中有一个使用 pandas 的类似示例。