Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Fill a ListView from a complex JSON



  • Hello to all,

    I'm new to the forum and also to QT.
    I am making a prototype for business purposes of a web app that we already have, and I want to transform it into an app to improve performance above all.

    I am creating a page to display an hourly programming of a thermostat.

    The programming is loaded by a JSON through a REST API that I load through Javascript. For the frontend I use QML as a language.

    I managed to get the model with all the information, but I can't visualize it as I would like.

    I get a single ListView with all the periods of each day only, arranged vertically, while I would like a row for each day, and in each day display x horizontally arranged rectangles, as many as there are periods.

    The example JSON is as follows:

    {"zone":"1","season":"summer","daily_schedule":[{"times_of_operation":[{"start":"0:00","stop":"6:30","temp":"29"},{"start":"6:30","stop":"8:30","temp":"26"},{"start":"8:30","stop":"17:00","temp":"30"},{"start":"17:00","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"monday"},{"times_of_operation":[{"start":"0:00","stop":"6:30","temp":"29"},{"start":"6:30","stop":"8:30","temp":"26"},{"start":"8:30","stop":"17:00","temp":"32"},{"start":"17:00","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"tuesday"},{"times_of_operation":[{"start":"0:00","stop":"6:30","temp":"29"},{"start":"6:30","stop":"8:30","temp":"26"},{"start":"8:30","stop":"17:00","temp":"32"},{"start":"17:00","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"wednesday"},{"times_of_operation":[{"start":"0:00","stop":"6:30","temp":"29"},{"start":"6:30","stop":"8:30","temp":"26"},{"start":"8:30","stop":"17:00","temp":"32"},{"start":"17:00","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"thursday"},{"times_of_operation":[{"start":"0:00","stop":"6:30","temp":"29"},{"start":"6:30","stop":"8:30","temp":"26"},{"start":"8:30","stop":"17:00","temp":"32"},{"start":"17:00","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"friday"},{"times_of_operation":[{"start":"0:00","stop":"8:30","temp":"29"},{"start":"8:30","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"29"}],"weekday":"saturday"},{"times_of_operation":[{"start":"0:00","stop":"8:30","temp":"29"},{"start":"8:30","stop":"22:00","temp":"26"},{"start":"22:00","stop":"24:00","temp":"30"}],"weekday":"sunday"}]}
    

    The periods are obtained from times_of_operation, and this is the code that I used to obtain the information and insert it in the listview.

    ListView
                                        {
                                            model: ListModel { id: model}
                                            delegate: myRectComp;
                                            width: parent.width
                                            height: parent.height
                                            spacing: 2 // 'b' space between elements
                                            //orientation:  Qt.Horizontal
                                            section.property: "weekday"
                                            section.criteria: ViewSection.FullString
                                            section.delegate: sectionHeading
                                        }
                                        Component.onCompleted: {
                                            var xhr = new XMLHttpRequest;
                                            xhr.open("GET", constants.baseURL + "/api/thermostat.php?zone=1&season=summer");
                                            xhr.onreadystatechange = function() {
                                                if (xhr.readyState === XMLHttpRequest.DONE) {
                                                    var data = JSON.parse(xhr.responseText);
                                                    model.clear();
                                                    var list = data["daily_schedule"];
                                                    for (var i in list) {
                                                        for (var k in list[i].times_of_operation) {
                                                            var start = list[i].times_of_operation[k].start;
                                                            var stop = list[i].times_of_operation[k].stop;
                                                            var temp = list[i].times_of_operation[k].temp;
                                                            var color = Schedule.color_map(temp, 'summer');
                                                            var width = ((Schedule.decode_time(stop) - Schedule.decode_time(start)) / 24) * window.width
                                                            model.append(
                                                                {
                                                                    'weekday': list[i]["weekday"],
                                                                    'myTemp': temp,
                                                                    'myWidth': width,
                                                                    'myColor': color,
                                                                    'myTime': start
                                                                }
                                                            );
                                                        }
                                                    }
                                                }
                                            }
                                            xhr.send();
                                        }
                                        Component {
                                            id: myRectComp;
                                            ColumnLayout {
                                                Rectangle {
                                                    color: myColor;
                                                    Text {
                                                        anchors.centerIn: parent
                                                        color: 'black'
                                                        text: myTemp
                                                        font.pixelSize: 12
                                                        font.bold: true
                                                    }
                                                    width: myWidth;
                                                    height: 50;
                                                }
                                                Rectangle {
                                                    color: '#000';
                                                    Text {
                                                        color: 'white'
                                                        text: myTime
                                                        font.pixelSize: 10
                                                        font.bold: true
                                                    }
                                                    width: myWidth;
                                                    height: 10;
                                                }
                                            }
                                        }
                                        Component {
                                            id: sectionHeading
                                            Rectangle {
                                                width: window.width
                                                height: childrenRect.height
                                                color: "#000"
    
                                                Text {
                                                    text: section
                                                    font.bold: true
                                                    color: 'white'
                                                    font.pixelSize: 12
                                                }
                                            }
                                        }
                                    }
    

    With this code I get the following result:

    alt text

    As already mentioned, the information I get and display is correct, but it is displayed incorrectly, because I have to group the rectangles under each day, in a single row.

    I've been banging my head for several days, I hope you can help me.

    Thank you


Log in to reply