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

Posted

技术标签:

【中文标题】是否可以将 QML 表视图连接到 python QAbstractModel 实例?【英文标题】:Is it possible to connect a QML Table view to a python QAbstractModel instance? 【发布时间】:2021-03-25 17:22:55 【问题描述】:

给定一个简单的 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 上?

【问题讨论】:

【参考方案1】:

您只需将模型导出到 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
        

    


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

【讨论】:

以上是关于是否可以将 QML 表视图连接到 python QAbstractModel 实例?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 和 QML:将 QML 信号连接到 C++ 插槽

无法将 Qml 信号连接到 C++ 插槽

使用 PySide2 将 python 信号连接到 QML ui 插槽

将 QML 信号连接到 PySide2 插槽

来自其他 QThread 的 Q_PROPERTY 将变量发送到 QML

What Joins 用于将多个表连接到一个视图中