How to use JSONListModel for qml ListView
-
I would like to use a json file to fill a ListView with content. To do this, I stumbled across JSONListModel. There you are redirected to an open source code. I have tried the code with the example, but without success.
I have created a new project by using Qt Design Studio (Qt 6.8.0). My Screen01.ui.qml file looks like this:import QtQuick import QtQuick.Controls import Example Rectangle { width: 400 height: 600 Column { spacing: 5 anchors.fill: parent anchors.margins: 5 anchors.bottomMargin: 0 Text { text: "JSON file data with subtree extraction: all books by title" } ListView { id: list1 width: parent.width height: 200 JSONListModel { id: jsonModel1 source: "jsonData.txt" query: "$.store.book[*]" } model: jsonModel1.model section.delegate: sectionDelegate section.property: "title" section.criteria: ViewSection.FirstCharacter delegate: Component { Text { width: parent.width horizontalAlignment: Text.AlignLeft font.pixelSize: 14 color: "black" text: model.title Text { anchors.fill: parent anchors.rightMargin: 5 horizontalAlignment: Text.AlignRight font.pixelSize: 12 color: "gray" text: model.author } } } } Text { text: "JSON file data with expression filter: books less than $10 by genre" } ListView { id: list2 width: parent.width height: 200 JSONListModel { id: jsonModel2 source: "jsonData.txt" query: "$..book[?(@.price<10)]" } model: jsonModel2.model section.delegate: sectionDelegate section.property: "category" section.criteria: ViewSection.FullString delegate: Component { Text { width: parent.width horizontalAlignment: Text.AlignLeft font.pixelSize: 14 color: "black" text: model.title Text { anchors.fill: parent anchors.rightMargin: 5 horizontalAlignment: Text.AlignRight font.pixelSize: 12 color: "gray" text: model.price } } } } Text { text: "JSON string data with substring filter: labels starting with 'A'" } ListView { id: list3 width: parent.width height: 100 JSONListModel { id: jsonModel3 json: '[ \ {"label": "Answer", "value": "42"}, \ {"label": "Pastis", "value": "51"}, \ {"label": "Alsace", "value": "67"}, \ {"label": "Alsace", "value": "68"} \ ]' query: "$[?(@.label.charAt(0)==='A')]" } model: jsonModel3.model delegate: Component { Text { width: parent.width horizontalAlignment: Text.AlignLeft font.pixelSize: 14 color: "black" text: model.label Text { anchors.fill: parent anchors.rightMargin: 5 horizontalAlignment: Text.AlignRight font.pixelSize: 12 color: "gray" text: model.value } } } } } Component { id: sectionDelegate Rectangle { color: "gray" width: parent.width height: sectionLabel.height Text { id: sectionLabel anchors.horizontalCenter: parent.horizontalCenter font.bold: true font.pixelSize: 16 color: "white" style: Text.Raised text: section } } } }
The JSONListModel.qml, jsonpath.js and jsonData.txt files are copied in the same folder as the screen01.ui.qml file.
I have been trying for a while now to find out why the json data is not being loaded into the ListView, but can't find the problem. Maybe someone can help me with this.
-
Hello! JSONListModel is not part of the Qt standard library. The wiki page points to the repository that implements the model: https://github.com/kromain/qml-utils
You can install it easily by copying theJSONListModel.qml
andjsonpath.js
into your project. Store them in a folder and add a qmldir file with the following content in order to make it a module that you can import in your project:module JSONListModel JSONListModel 1.0 JSONListModel.qml
The
module
value should match the folder name.
Also don't forget to add the corresponding import path, if necessary -
Hi. Thank you for your comment. This helps me to organize my project. But it still doesn't work. The problem might be that QML_XHR_ALLOW_FILE_READ is not set to 1. I receive the consol log :
Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.
To avoid this error I have changed my main.py file
import os import sys from pathlib import Path from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from autogen.settings import url, import_paths os.environ["QML_XHR_ALLOW_FILE_READ"] = "1" if __name__ == '__main__': app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() app_dir = Path(__file__).parent.parent engine.addImportPath(os.fspath(app_dir)) for path in import_paths: engine.addImportPath(os.fspath(app_dir / path)) engine.load(os.fspath(app_dir/url)) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())
As my jsonData.txt file is in my ExampleContent folder I expect it to be found. But no json content is available. I think there is a problem in updateJSONModel because I get the warning "No JSON content available":
function updateJSONModel() { console.log("[INFO] updateJSONModel() called."); jsonModel.clear(); if (json === "") { console.log("[WARNING] No JSON content available."); return; }
-
I solved my issue. Here is a more detailed resume of what I did:
The problem was that QML_XHR_ALLOW_FILE_READ wasn't set to 1. I received the consol log :
Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.
To avoid this error I have changed my main.py file
import os import sys from pathlib import Path from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from autogen.settings import url, import_paths os.environ["QML_XHR_ALLOW_FILE_READ"] = "1" if __name__ == '__main__': app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() app_dir = Path(__file__).parent.parent engine.addImportPath(os.fspath(app_dir)) for path in import_paths: engine.addImportPath(os.fspath(app_dir / path)) engine.load(os.fspath(app_dir/url)) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())
Additionally I have added an import to my ui.qml file:
import JSONListModel
and changed my source input from
JSONListModel { id: jsonModel1 source: "jsonData.txt" query: "$.store.book[*]" }
to
JSONListModel { id: jsonModel1 source: Qt.resolvedUrl("jsonData.txt") query: "$.store.book[*]" }
Which finally worked for me.
-