Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A collapsible nested list example in QML
import QtQuick 1.1
Item {
width: 200
height: 300
ListView {
anchors.fill: parent
model: nestedModel
delegate: categoryDelegate
}
ListModel {
id: nestedModel
ListElement {
categoryName: "Veggies"
collapsed: true
// A ListElement can't contain child elements, but it can contain
// a list of elements. A list of ListElements can be used as a model
// just like any other model type.
subItems: [
ListElement { itemName: "Tomato" },
ListElement { itemName: "Cucumber" },
ListElement { itemName: "Onion" },
ListElement { itemName: "Brains" }
]
}
ListElement {
categoryName: "Fruits"
collapsed: true
subItems: [
ListElement { itemName: "Orange" },
ListElement { itemName: "Apple" },
ListElement { itemName: "Pear" },
ListElement { itemName: "Lemon" }
]
}
ListElement {
categoryName: "Cars"
collapsed: true
subItems: [
ListElement { itemName: "Nissan" },
ListElement { itemName: "Toyota" },
ListElement { itemName: "Chevy" },
ListElement { itemName: "Audi" }
]
}
}
Component {
id: categoryDelegate
Column {
width: 200
Rectangle {
id: categoryItem
border.color: "black"
border.width: 5
color: "white"
height: 50
width: 200
Text {
anchors.verticalCenter: parent.verticalCenter
x: 15
font.pixelSize: 24
text: categoryName
}
Rectangle {
color: "red"
width: 30
height: 30
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
// Toggle the 'collapsed' property
onClicked: nestedModel.setProperty(index, "collapsed", !collapsed)
}
}
}
Loader {
id: subItemLoader
// This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null
// the Loader element retains the same height it had when sourceComponent was set. Setting visible
// to false makes the parent Column treat it as if it's height was 0.
visible: !collapsed
property variant subItemModel : subItems
sourceComponent: collapsed ? null : subItemColumnDelegate
onStatusChanged: if (status == Loader.Ready) item.model = subItemModel
}
}
}
Component {
id: subItemColumnDelegate
Column {
property alias model : subItemRepeater.model
width: 200
Repeater {
id: subItemRepeater
delegate: Rectangle {
color: "#cccccc"
height: 40
width: 200
border.color: "black"
border.width: 2
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
font.pixelSize: 18
text: itemName
}
}
}
}
}
}
@cjlitch
Copy link

cjlitch commented Dec 5, 2013

I have made something similar to this, do you know how to set the values of the nested ListElements? Similar to a nestedModel.get(0).subItems.get(2).itemName, but I want to set that property instead of get it.

@jianghaiying2002
Copy link

jianghaiying2002 commented Jan 17, 2014

Very helpful.
Thanks!

@blackbret94
Copy link

blackbret94 commented May 18, 2016

This is great - I don't know why the documentation doesn't have an example like this. Thanks!

@stoic1979
Copy link

stoic1979 commented Mar 7, 2017

Good work !

@testprojects
Copy link

testprojects commented Mar 25, 2019

Thank you for solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment