'Can't show api data in qml table correctly

I'm trying to get data from an api and insert it into table view from python side. Code.

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 1.4
import QtQuick.Controls 2.15

Window {
    width: 1200
    height: 500
    visible: true
    title: qsTr("TableView")

    Rectangle {
    anchors.fill: parent
    color: "#50505f"

    TableView {
        id: table

        anchors.fill: parent
        model: libraryModel

        rowDelegate: Rectangle {
            color: styleData.selected ? "5a53ff" : "#40405f"
            width: 2000
            height: 40
            border.width: 1
        }

        TableViewColumn {
            role: "title"
            title: "Title"
            width: 500
        }

        TableViewColumn {
            role: "author"
            title: "Author"
            width: 500
        }
    }
}

// Connections {
//     target: backend
// }
}

main.py

# This Python file uses the following encoding: utf-8
import os
import sys
from turtle import title
import requests
import json

from PySide2.QtCore import QObject, Slot, Signal
from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine


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

    # Get Context
    # main = MainWindow()
    url = "http://localhost:8085/api/supplier"
    response = requests.get(url).json()
    id = []
    name = []
    for obj in response:
        id.append(obj["supplier_id"])
        id.append(obj["supplier_name"])
    myModel = []

    engine.rootContext().setContextProperty("libraryModel", id) 

    engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

I understand what the error is, basically when the it calls the api it sets the first value it gets and sets it to both the fields, I want the data to be separated (id should go to title and name to author), but I can't seem to find a way to do it. Any help would be really appreciated. I've been working on it for quite a while and can't find a solution.



Solution 1:[1]

You have to use a model with custom roles associated with "title" and "author":

import os
import sys
import requests
import json

from PySide2.QtCore import QObject, Qt, Slot, Signal
from PySide2.QtGui import QStandardItem, QStandardItemModel
from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine

AUTHOR_ROLE = Qt.UserRole
TITLE_ROLE = Qt.UserRole + 1


class LibraryModel(QStandardItemModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setItemRoleNames({AUTHOR_ROLE: b"author", TITLE_ROLE: b"title"})

    def append(self, author, title):
        item = QStandardItem()
        item.setData(author, AUTHOR_ROLE)
        item.setData(title, TITLE_ROLE)
        self.appendRow(item)


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

    library_model = LibraryModel()

    # Get Context
    url = "http://localhost:8085/api/supplier"
    response = requests.get(url).json()

    for obj in response:
        author = obj["supplier_name"]
        title = obj["supplier_id"]
        library_model.append(author, title)

    engine.rootContext().setContextProperty("libraryModel", library_model)

    engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 eyllanesc