Riempire un ListView da un JSON complesso
-
Aha, I understand.
For me, it was then just to remove the anchors from the last example I sent, then adding orientation: ListView.Horizontal on the listview.
import QtQuick 2.1 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 ListView{ model: model delegate: myRectComp; width: 500 //(had to do this because of where i tested it..) height: parent.height orientation: ListView.Horizontal //added this clip:false spacing: 2 // 'b' space between elements //orientation: Qt.Horizontal Component { id: myRectComp; ColumnLayout { Rectangle { color: '#000'; Text { color: 'white' text: myTime font.pixelSize: 10 font.bold: true } width: myWidth; height: 10; } Rectangle { id:imLeft color: myColor; Text { anchors.centerIn: parent color: 'black' text: myTemp font.pixelSize: 12 font.bold: true } width: myWidth; height: 50; } } } Component { id: sectionHeading Rectangle { width: window.width height: childrenRect.height color: "#000" Text { text: section font.bold: true color: 'white' font.pixelSize: 12 } } } ListModel { id:model ListElement { myColor: "red"; myWidth: 100; myTime: "120"; myTemp:"1" } ListElement { myColor: "red"; myWidth: 150; myTime: "121"; myTemp:"1" } ListElement { myColor: "red"; myWidth: 100; myTime: "121"; myTemp:"1" } } }
-
I had already done this test, I have the same orientation effect: Qt.Horizontal.
In practice I have a single row arranged on a horizontal scrolling.
Instead I need the lines of every day arranged vertically, but the lines serve me arranged horizontally.
Let's say that the lines now look good, but they must be arranged vertically.
I hope I have been clear.
Try it with multiple lines, because your example apparently works because you tried only one line. Give an example like mine: use 7 days, and every day must have those rectangles arranged horizontally.
Thank you
-
I write here model that I have for example:
ListModel { id:model ListElement { weekday: "monday"; myColor: "red"; myWidth: 216.6; myTime: "0:00"; myTemp:"29" } ListElement { weekday: "monday"; myColor: "red"; myWidth: 66.66; myTime: "6:30"; myTemp:"26" } ListElement { weekday: "monday"; myColor: "red"; myWidth: 283.33; myTime: "8:30"; myTemp:"30" } ListElement { weekday: "monday"; myColor: "red"; myWidth: 166.66; myTime: "17:00"; myTemp:"26" } ListElement { weekday: "monday"; myColor: "red"; myWidth: 66.66; myTime: "22:00"; myTemp:"29" } ListElement { weekday: "tuesday"; myColor: "red"; myWidth: 216.6; myTime: "0:00"; myTemp:"29" } ListElement { weekday: "tuesday"; myColor: "red"; myWidth: 66.66; myTime: "6:30"; myTemp:"26" } ListElement { weekday: "tuesday"; myColor: "red"; myWidth: 283.33; myTime: "8:30"; myTemp:"30" } ListElement { weekday: "tuesday"; myColor: "red"; myWidth: 166.66; myTime: "17:00"; myTemp:"26" } ListElement { weekday: "tuesday"; myColor: "red"; myWidth: 66.66; myTime: "22:00"; myTemp:"29" } .... ListElement { weekday: "sunday"; myColor: "red"; myWidth: 283.26; myTime: "0:00"; myTemp:"29" } ListElement { weekday: "sunday"; myColor: "red"; myWidth: 450; myTime: "8:30"; myTemp:"26" } ListElement { weekday: "sunday"; myColor: "red"; myWidth: 66.66; myTime: "22:00"; myTemp:"30" } }
The Width of each of the rectangles must make 800 which is the width of the screen. But for testing this is irrelevant.
This is the model more or less, I need to arrange it as I showed in the previous photo.
Thank you
-
This is very hard to do with listview. As a listview inside another listview is very challenging.
But I will create a solution the way I would do it for this sort of project when i get back up again, if no one else has by then :)
-
Could not go to sleep just yet!
Here is a example I modified to fit your purpose a bit better than it was originally, with some creative thinking it should go ok to implement this? Basically you just have to parse the json days (after removing duplicates) into model1 then parse the rest of te data to model2import QtQuick 2.1 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 Rectangle { width: 800 height: 500 ListModel { id: model1 ListElement { name: "Monday" } ListElement { name: "Tuesday" } ListElement { name: "Wednsday" } } ListModel { id: model2 ListElement { time: "00" temp: "23" } ListElement { time: "06" temp: "22" } ListElement { time: "08" temp: "24" } } Component { id: delegate2 Item { width: 100 height: col2.childrenRect.height Column { id: col2 anchors.left: parent.left anchors.right: parent.right Text { id: times text: time } Text { anchors.top:times.bottom id: temps text: temp } } } } ListView { width: 800 id: outer model: model1 delegate: listdelegate anchors.fill: parent } Component { id: listdelegate Item { width: 500 height: col.childrenRect.height Column { id: col anchors.left: parent.left anchors.right: parent.right Text { id: t1 text: name } ListView { id: insidelist model: model2 delegate: delegate2 contentHeight: contentItem.childrenRect.height height: childrenRect.height anchors.left: parent.left anchors.right: parent.right clip: false orientation: ListView.Horizontal } } } } }
-
Hello
Of small improvements, however there are errors in the console:
QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function.
Hoever I have the effect that every day I repeat the same line, which is the same effect that I had had some time ago doing everything differently.
Monday has data different from Tuesday, but Monday's data repeats them the same on all days. I have to distinguish the days in the model when I fill the second listview. How can I do?
And another thing. Every day has daily data from Monday to Sunday, which scrolls horizontally. I think the problem lies with how I build the model in the javascript part.
Thank you
Thank you
-
Morning :)
Yes column does not like that... which is why it's better to use treeview, or leave out the column.
Only thing then is to properly align the elements yourself with anchors etc.Hmm, "And another thing. Every day has daily data from Monday to Sunday, which scrolls horizontally."
So you can scroll down from money to tuesday, and also scroll to the right to see tuesday too? or how do you mean?The double list I sent last night is possible if you dynamicly add listmodels and id's. I have done this with 3D Objects, but not with listmodels, so not quite sure if it will work.
Another way is to use sub-list elements, but then again there is a need to do some changes to parsing, I think that this is the easiest way to achieve what you want without tableview etc
import QtQuick 2.14 Rectangle { width: 200; height: 200 ListModel { id: daysModel ListElement { day: "monday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "tuesday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "wedsday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "thursday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "friday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "saturday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } ListElement { day: "sunday" times: [ ListElement { description: "00:00" }, ListElement { description: "06:30" } ] temps: [ ListElement { description: "17" }, ListElement { description: "21" } ] } } Component { id: daysDelegate Item { width: 200; height: 50 Text { id: nameField; text: day } Row { id:firstRow anchors.top: nameField.bottom spacing: 5 Text { text: "times:" } Repeater { model: times Text { text: description } } } Row { id:secondRow anchors.top: firstRow.bottom spacing: 5 Text { text: "temps:" } Repeater { model: temps Text { text: description } } } } } ListView { id:listView anchors.fill: parent clip:true model: daysModel delegate: daysDelegate } Rectangle { anchors.top:listView.bottom height:20 Text { id: name text: daysModel.get(0).times.get(1).description; } } }
Here you just need to foreach all monday elements you have (for that one monday), and append the time to times and temp to temps.
-
I found a solution on gui. With this model I can fillgui correctly:
ListModel { id: model ListElement { name: "monday" attributes: [ ListElement { myWidth: 216.6 myColor: "red" myTemp: "29°" myTime: "0:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "26°" myTime: "6:30" }, ListElement { myWidth: 283.33 myColor: "red" myTemp: "30°" myTime: "8:30" }, ListElement { myWidth: 166.66 myColor: "red" myTemp: "26°" myTime: "17:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "29°" myTime: "22:00" } ] } ListElement { name: "tuesday" attributes: [ ListElement { myWidth: 216.6 myColor: "red" myTemp: "29°" myTime: "0:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "26°" myTime: "6:30" }, ListElement { myWidth: 283.33 myColor: "red" myTemp: "32°" myTime: "8:30" }, ListElement { myWidth: 166.66 myColor: "red" myTemp: "26°" myTime: "17:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "29°" myTime: "22:00" } ] } ListElement { name: "wednsday" attributes: [ ListElement { myWidth: 216.6 myColor: "red" myTemp: "29°" myTime: "0:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "26°" myTime: "6:30" }, ListElement { myWidth: 283.33 myColor: "red" myTemp: "32°" myTime: "8:30" }, ListElement { myWidth: 166.66 myColor: "red" myTemp: "26°" myTime: "17:00" }, ListElement { myWidth: 66.66 myColor: "red" myTemp: "29°" myTime: "22:00" } ] } }
And this is delegate:
Component { id: myRectComp; Item { width: 800; height: 90 ColumnLayout { id: scheduleList Label { id: weekday color: 'white' text: name font.pixelSize: 10 font.bold: true } RowLayout { spacing: 2 Repeater { model: attributes ColumnLayout { Rectangle { width: myWidth height: 50 color: myColor Label { anchors.centerIn: parent color: 'black' text: myTemp font.pixelSize: 12 font.bold: true } } Rectangle { width: myWidth height: 40 color: '#000' Label { color: 'white' text: myTime font.pixelSize: 9 font.bold: true } } } } } } }
But only miss part on javascript for fill by json this listModel.
I think that will be something like this:
fruitModel.append(..., "attributes": [{"myWidth":216,"myTemp":"29°"}, {"myWidth":66,"myTemp":"30°"}]);
Now try and keep inform if works. For now thanks.
-
That was sort of the same i sent you, or exactly the same actually..
So just parse the data as i described and it'll work fine :)
-
daysModel.append({
"day": "new day",
"times": [{"description": "00:00"}, {"description": "06:00"}],
"temps": [{"description": "17"}, {"description": "21"}]
})Works fine on mine. So yours should be ok.
Good work :)
-
I found a solution: edit component at this way:
Component.onCompleted: { var weekdays = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]; 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 json = JSON.parse(xhr.responseText); model.clear(); var list = json["daily_schedule"]; for (var i in list) { var day=[]; if (json.daily_schedule[i]) { for (var k in json.daily_schedule[i].times_of_operation) { var start = json.daily_schedule[i].times_of_operation[k].start; var stop = json.daily_schedule[i].times_of_operation[k].stop; var temp = json.daily_schedule[i].times_of_operation[k].temp; // If json file schedule contain daily schedule, get start, stop and temperature of each period and zone if (json.daily_schedule[i].weekday === weekdays[i]) { var rowDay = { myWidth: ((Schedule.decode_time(stop) - Schedule.decode_time(start)) / 24) * 800, myColor: Schedule.color_map(temp, 'summer'), myTemp: temp, myTime: start }; day.push(rowDay); } } model.append({ "weekday": list[i]["weekday"], "attributes": day }) } } } } xhr.send(); }
Thank you very much.
Now I have others problem tobesolved, but for now I resolve this and thank you.
-
I'm trying to edit the created listView, in particular the attributes part. In particular I want to delete a period and then change the size of the previous one.
Basically I open a new page where I show the single day with the list of the periods of that day, and from there I can call the function that removes the period, and on that page everything seems ok.
When I close the page, however, in the main one I don't see the updated model. I see the period removed (even if sometimes it does strange things and it doesn't even do that) and the size is not updated (also here sometimes it does and sometimes it doesn't)
The period removal code is this:
function removePeriod(indexWeekday, weekday, index) { var modelData = model.get(indexWeekday); var newWidth = modelData.attributes.get(index - 1).myWidth + modelData.attributes.get(index).myWidth var newStop = modelData.attributes.get(index).myStop; console.log("Index Weekday: " + indexWeekday) console.log("Weekday: " + weekday) console.log("Index: " + index) console.log("New Width: " + newWidth) console.log("New Stop: " + newStop) modelData.attributes.remove(index); modelData.attributes.set(index - 1, {myWidth: newWidth}); modelData.attributes.set(index - 1, {myStop: newStop}); var day = []; for (var i = 0; i < modelData.attributes.count; i++) { day.push(modelData.attributes.get(i)); } model.set(indexWeekday, {"weekday": weekday, "attributes": day}) scheduleSinglePeriod.remove(index); scheduleSinglePeriod.set(index - 1, {"myWidth": newWidth}); }
Thank you
-
I resolved replaced model.set with these 2 lines:
model.insert(indexWeekday, {"weekday": weekday, "attributes": day}) model.remove(indexWeekday + 1)
I don't know if this code is clear and if it is a good way for update model.
I insert day row correctly on correct index sometimes I remove a period, and after remove next index, that is old day duplicated.
Thanks
-
@MEMekaniske This part works. I ask if is clear way how do it. Now I have some problems with clock timer. I open another post.
Thanks