Parsing Json with QML



  • Hi,

    As QML does not have any Json model, what remains the best way to parse Json data ? I had a look at couple of alternatives. Some of which previously explained here:

    http://developer.qt.nokia.com/forums/viewthread/2057

    But not sure about which one to use. Right now I'm using raw Javascript code to fetch and parse Json, and set properties (instead of creating models). I'm not willing to mess up with C++ code right now. What's the best way to parse Json in QML ? Is there any progress from Nokia in this direction ?



  • I would still recommend qjson. Even though it is C++ it is so easy to use that it is silly ;-)



  • Not sure. I guess it depends what you are looking for. Do you need some kind of model implementation that works based on JSON so you can use it with your views? That is actually not a bad idea, IMHO. Something like QXmlListModel, but for JSON?

    Edit:
    I am not the first one to think of this, obviously. There is an existing "suggestion":http://bugreports.qt.nokia.com/browse/QTBUG-12117 in the bugtracker. You might want to vote for that.



  • Hi,

    Done voting !!! Right now I'm not doing any complex and repetitive operation on json data, so simple javascript won't hurt, but as complexity of data increases, I thought a model would be better idea. I think I would have to introduce C++ code in my application. Any sample code for how to create QXmlListModel like model for Json. (except the code shown in bug tracker)



  • Hello here is my point of view! I tested everything! XMLModel, javascript XML parser, C++ side parser etc...

    Do Not use C++ Json parser : Because exchange data between c++ and QML is slow

    Make a Javascript parser ! It's more easy with eval ! Here is an example :

    Json data
    @
    {"index":["all"],"flux":{"all":[{"data":{"title":"boris","icon":"icon.png"}]}}
    @

    QML side : main.qml
    @
    import QtQuick 1.0
    import "parser.js" as JS

    Item {
    id:root
    width: 360
    height: 640

    Component.onCompleted: JS.load()
    
    
    ListModel {  id:listModel }
    
    ListView {
        id:view
        anchors.fill:parent
        model : listModel
        delegate: Rectangle {
             width:parent.width
             height:80
             Text {
             anchors.center:parent
             text: title
             }
           
        }
    }
    

    }
    @

    javascript side : parser.js

    @
    function load() {

    listModel.clear();
    var xhr = new XMLHttpRequest();
    

    xhr.open("GET","http://data.json",true);
    xhr.onreadystatechange = function()
    {
    if ( xhr.readyState == xhr.DONE)
    {
    if ( xhr.status == 200)
    {
    var jsonObject = eval('(' + xhr.responseText + ')');
    loaded(jsonObject)
    }
    }
    }
    xhr.send();
    }

    function loaded(jsonObject)
    {
    for ( var index in jsonObject.flux.all )
    {
    listModel.append({
    "title" : jsonObject.flux.all[index].data["title"],
    "icon" : jsonObject.flux.all[index].data["icon"]});
    }

    // get directly the json object. Should work but not tested
    //listModel.append({jsonObject.flux.all});

    }
    @



  • Thanks for your sample codes, but it seems not work still, such as "anchors.center" should "anchors.centerIn:"
    And how to put the JSON data into a place, which http address is able to access to.

    [quote author="dridk" date="1308668221"]Hello here is my point of view! I tested everything! XMLModel, javascript XML parser, C++ side parser etc...

    Do Not use C++ Json parser : Because exchange data between c++ and QML is slow

    Make a Javascript parser ! It's more easy with eval ! Here is an example :

    Json data
    @
    {"index":["all"],"flux":{"all":[{"data":{"title":"boris","icon":"icon.png"}]}}
    @

    QML side : main.qml
    @
    import QtQuick 1.0
    import "parser.js" as JS

    Item {
    id:root
    width: 360
    height: 640

    Component.onCompleted: JS.load()
    
    
    ListModel {  id:listModel }
    
    ListView {
        id:view
        anchors.fill:parent
        model : listModel
        delegate: Rectangle {
             width:parent.width
             height:80
             Text {
             anchors.center:parent
             text: title
             }
           
        }
    }
    

    }
    @

    javascript side : parser.js

    @
    function load() {

    listModel.clear();
    var xhr = new XMLHttpRequest();
    

    xhr.open("GET","http://data.json",true);
    xhr.onreadystatechange = function()
    {
    if ( xhr.readyState == xhr.DONE)
    {
    if ( xhr.status == 200)
    {
    var jsonObject = eval('(' + xhr.responseText + ')');
    loaded(jsonObject)
    }
    }
    }
    xhr.send();
    }

    function loaded(jsonObject)
    {
    for ( var index in jsonObject.flux.all )
    {
    listModel.append({
    "title" : jsonObject.flux.all[index].data["title"],
    "icon" : jsonObject.flux.all[index].data["icon"]});
    }

    // get directly the json object. Should work but not tested
    //listModel.append({jsonObject.flux.all});

    }
    @[/quote]



  • Instead of:

    @var jsonObject = eval(’(’ + xhr.responseText + ‘)’); @

    one can simply use in QML (without any imports or includes):

    @ var jsonObject = JSON.parse(xhr.responseText); @

    It is safer and may actually be faster (if it is not already, with Qt5 it will be).



  • [quote author="dridk" date="1308668221"]Hello here is my point of view! I tested everything! XMLModel, javascript XML parser, C++ side parser etc...

    Do Not use C++ Json parser : Because exchange data between c++ and QML is slow

    Make a Javascript parser ! It's more easy with eval ! Here is an example :

    Json data
    @
    {"index":["all"],"flux":{"all":[{"data":{"title":"boris","icon":"icon.png"}]}}
    @

    QML side : main.qml
    @
    import QtQuick 1.0
    import "parser.js" as JS

    Item {
    id:root
    width: 360
    height: 640

    Component.onCompleted: JS.load()
    
    
    ListModel {  id:listModel }
    
    ListView {
        id:view
        anchors.fill:parent
        model : listModel
        delegate: Rectangle {
             width:parent.width
             height:80
             Text {
             anchors.center:parent
             text: title
             }
           
        }
    }
    

    }
    @

    javascript side : parser.js

    @
    function load() {

    listModel.clear();
    var xhr = new XMLHttpRequest();
    

    xhr.open("GET","http://data.json",true);
    xhr.onreadystatechange = function()
    {
    if ( xhr.readyState == xhr.DONE)
    {
    if ( xhr.status == 200)
    {
    var jsonObject = eval('(' + xhr.responseText + ')');
    loaded(jsonObject)
    }
    }
    }
    xhr.send();
    }

    function loaded(jsonObject)
    {
    for ( var index in jsonObject.flux.all )
    {
    listModel.append({
    "title" : jsonObject.flux.all[index].data["title"],
    "icon" : jsonObject.flux.all[index].data["icon"]});
    }

    // get directly the json object. Should work but not tested
    //listModel.append({jsonObject.flux.all});

    }
    @[/quote]

    Hi,
    My name is wilson. I have test out using this method to parsing Json with Xml.
    But when I click on the page, it shown a blank page.
    May I know why is this happen??


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.