In this blog post, we'll explore the creation of a TreeView in QML without the use of external libraries. We'll achieve this by implementing a custom AppTreeView
component. This TreeView is versatile and allows for recursive nesting, making it suitable for displaying hierarchical data structures.
Implementation Details
The AppTreeView
component consists of a Column
with a Repeater
. Within the Repeater
, we have a CheckBox
and a Loader
. When the CheckBox
is checked, a new instance of AppTreeView
is created, allowing for the recursive display of child nodes.
The data for the TreeView is stored in a JavaScript object. We use a model
property to bind the data to the TreeView. This model can be any JavaScript object containing hierarchical data.
import QtQuick
import QtQuick.Controls
Page {
property var m: ({
text: "Springfield People",
children: ["simpsons", "flanders"],
"simpsons": {
text: "Simpsons",
children: ["homer", "marge"],
"homer": {
text: "Homer Simpson",
children: ["bart", "lisa", "maggie"],
bart : { text: "Bart Simpson" },
lisa : { text: "Lisa Simpson" },
maggie: { text: "Maggie Simpson" }
},
"marge": { text: "Marge Simpson" }
},
"flanders": {
text: "Flanders",
children: ["ned", "maude"],
"ned": {
text: "Ned Flanders",
children: ["rod", "todd"],
"rod": { text: "Rod Flanders" },
"todd": { text: "Todd Flanders" }
},
"maude": { text: "Maude Flanders" }
}
})
AppTreeView {
model: m
}
}
//AppTreeView.qml
import QtQuick
import QtQuick.Controls
Column {
id: tv
property var model
property var text: (model && model.text) || "root"
Button {
id: checkBox
text: tv.text
icon.source: checked ? "chevron-down.svg" : "chevron-right.svg"
checkable: true
}
Repeater {
model: checkBox.checked ? tv.model.children : 0
delegate: Column {
x: 30
Loader { id: loader }
Component.onCompleted: {
let m = { name: modelData, value: modelData, nodes: [ ] };
if (modelData in tv.model) m = tv.model[modelData];
loader.setSource("AppTreeView.qml",
{
model: m,
text: m.text || modelData
} );
}
}
}
}
Styling the TreeView
To enhance the visual appeal of the TreeView, we've included SVG icons for the CheckBox
, which change based on whether the node is expanded or collapsed.
// chevron-right.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path stroke="transparent" stroke-width="1" fill="black" d="M 16 8 L 24 16 L 16 24"/>
</svg>
// chevron-down.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path stroke="transparent" stroke-width="1" fill="black" d="M 8 16 L 24 16 L 16 24"/>
</svg>
Conclusion
With this custom AppTreeView
component, we have created a fully functional TreeView in QML without relying on external libraries. The TreeView is highly customizable and adaptable to various data structures, making it a versatile tool for building user interfaces.