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. ListModel and JSON Parsing in QML

ListModel and JSON Parsing in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 3 Posters 670 Views
  • 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.
  • D Offline
    D Offline
    Drazz
    wrote on last edited by
    #1

    Hello everyone,

    I'm working on a QML application where I'm trying to parse a JSON string and populate a ListModel with the data and plot some charts. However, I'm encountering a couple of issues related to accessing the model data.

    Here’s a snippet of my code:

    import QtQuick
    import QtQuick.Window
    import QtCharts
    
    Window {
        width: 640
        height: 480
        visible: true
    
        readonly property string json: "[{\"data\": [1,2,3]},{\"data\": [4,5,6]}]"
        property ListModel myModel: ListModel {}
    
        function parseJson(json) {
            try {
                var obj = JSON.parse(json);
                if (obj) {
                    obj.forEach(function(item) {
                        console.log("json data: " + item.data)
                        myModel.append({
                            data: item.data
                        });
                    });
                }
            } catch (e) {
                console.error("QML JSON parse error: ", e);
            }
        }
    
        Component.onCompleted: parseJson(json);
    
        ListView {
            anchors.fill: parent
    
            model: myModel
            delegate: ChartView {
                width: 500
                height: 300
    
                LineSeries {
                    id: lineSeries
                    Component.onCompleted: plot()
    
                    function plot() {
                        console.log("model.data: " + model.data)
                        console.log("model.data.length: " + model.data.length)
    
                        lineSeries.clear()
                        model.data.forEach(function(value, index) {
                            lineSeries.append(index, value);
                        });
                    }
                }
            }
        }
    }
    

    Output:

    qml: json data: 1,2,3
    qml: json data: 4,5,6
    qml: model.data: QQmlListModel(0x131e185e780)
    qml: model.data.length: undefined
    qrc:/qt/qml/TestQmlListView/Main.qml:50: TypeError: Property 'forEach' of object QQmlListModel(0x131e185e780) is not a function
    

    When I log model.data, it shows QQmlListModel, but I can't access its contents using forEach. The length property is also undefined. How can I correctly iterate through the data stored in ListModel?

    Thank you!

    B 1 Reply Last reply
    0
    • D Drazz

      Hello everyone,

      I'm working on a QML application where I'm trying to parse a JSON string and populate a ListModel with the data and plot some charts. However, I'm encountering a couple of issues related to accessing the model data.

      Here’s a snippet of my code:

      import QtQuick
      import QtQuick.Window
      import QtCharts
      
      Window {
          width: 640
          height: 480
          visible: true
      
          readonly property string json: "[{\"data\": [1,2,3]},{\"data\": [4,5,6]}]"
          property ListModel myModel: ListModel {}
      
          function parseJson(json) {
              try {
                  var obj = JSON.parse(json);
                  if (obj) {
                      obj.forEach(function(item) {
                          console.log("json data: " + item.data)
                          myModel.append({
                              data: item.data
                          });
                      });
                  }
              } catch (e) {
                  console.error("QML JSON parse error: ", e);
              }
          }
      
          Component.onCompleted: parseJson(json);
      
          ListView {
              anchors.fill: parent
      
              model: myModel
              delegate: ChartView {
                  width: 500
                  height: 300
      
                  LineSeries {
                      id: lineSeries
                      Component.onCompleted: plot()
      
                      function plot() {
                          console.log("model.data: " + model.data)
                          console.log("model.data.length: " + model.data.length)
      
                          lineSeries.clear()
                          model.data.forEach(function(value, index) {
                              lineSeries.append(index, value);
                          });
                      }
                  }
              }
          }
      }
      

      Output:

      qml: json data: 1,2,3
      qml: json data: 4,5,6
      qml: model.data: QQmlListModel(0x131e185e780)
      qml: model.data.length: undefined
      qrc:/qt/qml/TestQmlListView/Main.qml:50: TypeError: Property 'forEach' of object QQmlListModel(0x131e185e780) is not a function
      

      When I log model.data, it shows QQmlListModel, but I can't access its contents using forEach. The length property is also undefined. How can I correctly iterate through the data stored in ListModel?

      Thank you!

      B Offline
      B Offline
      Bob64
      wrote on last edited by
      #2

      @Drazz said in ListModel and JSON Parsing in QML:

      How can I correctly iterate through the data stored in ListModel?

      The API available on ListModel is described in the documentation.

      You need to use the count property and the get(index) method. You can use these to write a straightforward for loop.

      1 Reply Last reply
      1
      • D Offline
        D Offline
        Drazz
        wrote on last edited by
        #3

        @Bob64

        Thanks for your help but I haven't had any success yet. This is the change I've made based on your suggestion:

        function plot() {
                            console.log("model.data: " + model.data)
                            console.log("model.data.count: " + model.data.count)
        
                            lineSeries.clear()
                            for (var i = 0; i < model.data.count; i++) {
                                console.log("Model " + i + " data " + model.data.get(i) + " value: " + valueOf(model.data.get(i)))
                                lineSeries.append(i, model.data.get(i))
                            }
                        }
        

        And I get this output:

        qml: json data: 1,2,3
        qml: json data: 4,5,6
        qml: model.data: QQmlListModel(0x25f365eb2e0)
        qml: model.data.count: 3
        qml: Model 0 data QObject(0x25f3679f160) value: DeclarativeLineSeries_QML_1(0x25f361b1db0)
        Ignored NaN, Inf, or -Inf value.
        qml: Model 1 data QObject(0x25f3679f6b0) value: DeclarativeLineSeries_QML_1(0x25f361b1db0)
        Ignored NaN, Inf, or -Inf value.
        qml: Model 2 data QObject(0x25f3679da00) value: DeclarativeLineSeries_QML_1(0x25f361b1db0)
        Ignored NaN, Inf, or -Inf value.
        qml: model.data: QQmlListModel(0x25f365ee220)
        qml: model.data.count: 3
        qml: Model 0 data QObject(0x25f3679e060) value: DeclarativeLineSeries_QML_1(0x25f367f4980)
        Ignored NaN, Inf, or -Inf value.
        qml: Model 1 data QObject(0x25f3679e390) value: DeclarativeLineSeries_QML_1(0x25f367f4980)
        Ignored NaN, Inf, or -Inf value.
        qml: Model 2 data QObject(0x25f3679de40) value: DeclarativeLineSeries_QML_1(0x25f367f4980)
        Ignored NaN, Inf, or -Inf value.
        
        1 Reply Last reply
        0
        • D Offline
          D Offline
          Drazz
          wrote on last edited by Drazz
          #4

          This work arround works:

          [...]
          readonly property string json: "[{\"data\": [1,2,3]},{\"data\": [4,5,6]}]"
          property ListModel myModel: ListModel {}
          
              function parseJson(json) {
                  try {
                      var obj = JSON.parse(json);
                      if (obj) {
                          obj.forEach(function(item) {
          
                              console.log("json data: " + item.data)
          
                              var dataObj= []
                              item.data.forEach(function(element) {
                                  dataObj.push({"value" : element})
                              })
          
                              myModel.append({
                                                 data: dataObj
                                             });
                          });
                      }
                  } catch (e) {
                      console.error("QML JSON parse error: ", e);
                  }
              }
          
          [...]
          
          function plot() {
                              console.log("model.data: " + model.data)
                              console.log("model.data.count: " + model.data.count)
          
                              lineSeries.clear()
                              for (var i = 0; i < model.data.count; i++) {
                                  console.log("DataIdx " + i + " dataValue " + model.data.get(i).value)
                                  lineSeries.append(i, model.data.get(i).value)
                              }
                          }
          

          Is this the best way to do this?

          1 Reply Last reply
          0
          • GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            https://github.com/benlau/qsyncable does this with its JsonListModel.

            All you have to do is source: JSON.parse(json) and it will diff the model with the previous version and emit corresponding signals (rowsInserted/removed, dataChanged, ...)

            1 Reply Last reply
            2
            • D Offline
              D Offline
              Drazz
              wrote on last edited by
              #6

              @GrecKo

              Wow, this looks interesting. Thanks for sharing

              1 Reply Last reply
              0
              • D Drazz 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