Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to use JSONListModel for qml ListView
Forum Updated to NodeBB v4.3 + New Features

How to use JSONListModel for qml ListView

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 576 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alvib
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • Jaime02J Offline
      Jaime02J Offline
      Jaime02
      Qt Champion 2021
      wrote on last edited by Jaime02
      #2

      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 the JSONListModel.qml and jsonpath.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

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Alvib
        wrote on last edited by Alvib
        #3

        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;
                }
        
        1 Reply Last reply
        0
        • A Offline
          A Offline
          Alvib
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          1
          • A Alvib has marked this topic as solved on

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved