[Python] QAbstractTableModel from Python to QML

Discussão em 'Python' iniciado por Stack, Março 9, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to visualize dictionary data inside QML application. Can anyone guide me what I am doing wrong? The data in the dictionary will change during the program's execution, so it would be good to have signals implemented as well. The PointsTableModel must use data from the ProjectManagement class.

    I have managed to get it work using Qt.labs.qmlmodels, TableModel, TableModelColumns, etc, but it is very messy and I want to have control over it from python.

    main.py

    import sys
    from pathlib import Path

    from PySide6.QtGui import QGuiApplication
    from PySide6.QtQml import QQmlApplicationEngine
    from PySide6.QtCore import QObject, Property

    from ProjectManagement import ProjectManagement


    class BG(QObject):
    def __init__(self):
    QObject.__init__(self)
    self._pm = ProjectManagement()

    @Property(QObject, constant=True)
    def pm(self):
    return self._pm


    if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    background = BG()
    engine.rootContext().setContextProperty("bg", background)

    qml_file = Path(__file__).resolve().parent / "main.qml"
    engine.load(qml_file)

    app.aboutToQuit.connect(engine.deleteLater)
    if not engine.rootObjects():
    sys.exit(-1)
    sys.exit(app.exec())


    ProjectManagement.py

    from PySide6 import QtCore


    class ProjectManagement(QtCore.QObject):
    def __init__(self):
    QtCore.QObject.__init__(self)

    print("ProjectManagement START")
    data = [
    {
    "Id": "1",
    "Coordinates": [
    {
    "X": " 5477262.484",
    "Y": " 7447371.856",
    "Z": " 639.947"
    }
    ],
    "Code": "",
    "Value": " 48",
    "Date": "",
    "Comment": " 4.947",
    "Text": "",
    "Symbol": "",
    "Color": "#000000",
    "Scale": 1,
    "Visible": True,
    "Visible text": True
    },
    {
    "Id": "2",
    "Coordinates": [
    {
    "X": " 5477262.496",
    "Y": " 7447371.946",
    "Z": " 639.911"
    }
    ],
    "Code": "",
    "Value": " 26",
    "Date": "",
    "Comment": " 4.911\n",
    "Text": "",
    "Symbol": "",
    "Color": "#000000",
    "Scale": 1,
    "Visible": True,
    "Visible text": True
    },
    {
    "Id": "3",
    "Coordinates": [
    {
    "X": " 5477262.440",
    "Y": " 7447372.086",
    "Z": " 640.088"
    }
    ],
    "Code": "",
    "Value": " 2",
    "Date": "",
    "Comment": " 5.088\n",
    "Text": "",
    "Symbol": "",
    "Color": "#000000",
    "Scale": 1,
    "Visible": True,
    "Visible text": True
    },
    {
    "Id": "4",
    "Coordinates": [
    {
    "X": " 5477262.468",
    "Y": " 7447372.128",
    "Z": " 640.106"
    }
    ],
    "Code": "",
    "Value": " 3",
    "Date": "",
    "Comment": " 5.106",
    "Text": "",
    "Symbol": "",
    "Color": "#000000",
    "Scale": 1,
    "Visible": True,
    "Visible text": True
    }
    ]
    self.tab_model = PointsTableModel(data)
    print(self.tab_model.rowCount())


    class PointsTableModel(QtCore.QAbstractTableModel):
    def __init__(self, database):
    QtCore.QAbstractTableModel.__init__(self)

    print("PointsTableModel START")
    self.database = database

    def rowCount(self, parent=QtCore.QModelIndex()):
    return len(self.database)

    def columnCount(self, parent=QtCore.QModelIndex()):
    return 14

    def headerData(self, section, orientation, role):
    if orientation == QtCore.Qt.Horizontal:
    return ('Vis', 'Id', 'X', 'Y', 'Z', 'Code', 'Val', 'Date', 'Com', 'Txt', 'Txt vis', 'Symbol', 'Color', 'Scale')[section]
    else: # vertical
    return f"{section}"

    def data(self, index=QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole):
    column = index.column()
    row = index.row()

    if role == QtCore.Qt.DisplayRole:
    row_data = self.database[row]
    if column == 0:
    return row_data['Visible']
    elif column == 1:
    return row_data['Id']
    elif column == 2:
    return row_data['Coordinates'][0]['X']
    elif column == 3:
    return row_data['Coordinates'][0]['Y']
    elif column == 4:
    return row_data['Coordinates'][0]['Z']
    elif column == 5:
    return row_data['Code']
    elif column == 6:
    return row_data['Value']
    elif column == 7:
    return row_data['Date']
    elif column == 8:
    return row_data['Comment']
    elif column == 9:
    return row_data['Text']
    elif column == 10:
    return row_data['Visible text']
    elif column == 11:
    return row_data['Symbol']
    elif column == 12:
    return row_data['Color']
    elif column == 13:
    return row_data['Scale']
    return None


    main.qml

    import QtQuick
    import QtQuick.Window
    import QtQuick.Controls


    Window {
    title: qsTr("Hello World")
    visible: true
    visibility: Qt.WindowFullScreen

    HorizontalHeaderView {
    id: horizontalHeader
    anchors.left: tabView.left
    anchors.top: parent.top
    syncView: tabView
    clip: true
    model: tabView.model.headerData
    }

    VerticalHeaderView {
    id: verticalHeader
    anchors.top: tabView.top
    anchors.left: parent.left
    syncView: tabView
    clip: true
    }

    TableView {
    id: tabView
    anchors.left: verticalHeader.right
    anchors.top: horizontalHeader.bottom
    anchors.right: parent.right
    anchors.bottom: parent.bottom
    clip: true
    columnSpacing: 10
    rowSpacing: 10

    model: bg.pm.tab_model
    delegate: Button {
    text: model.display
    highlighted: true
    }
    }
    }

    Continue reading...

Compartilhe esta Página