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

How to use JSONListModel for qml ListView

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 1.0k 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