Latest:
- Sailfish OS and memory
- Hillshade tile server
- Statistics of OSM Scout for Sailfish OS
- Nebezpečný router
- Tree model with Silica components
By month:
- November 2021
- January 2019
- December 2017
- December 2016
- May 2014
- April 2014
- November 2013
- April 2013
- April 2011
- February 2011
- January 2011
- August 2010
- May 2010
- March 2010
- January 2010
- October 2009
- April 2009
- February 2009
- October 2008
- September 2008
- August 2008
- April 2008
- March 2008
- February 2008
Topic:
Tree model with Silica components
When you have Qt data model representing tree
(QAbstractItemModel),
you can use TreeView
component when you are creating UI with QtQuick.

But what to do when there is no similar native component for your platform?
It is the case of Silica, native components for Sailfish OS – great mobile OS from Finnish
company Jolla. I face this problem some days ago when I was creating map
downloader for OSM
Scout. Model of available maps represents tree of continents, countries and
regions. I found inspiration in native File Browser where
every directory is opened as a new page – it perfectly fits to Sailfish look
& feel. But how to implement this behavior just in QML? Answer is DelegateModel
from QtQml.Models.
For list entries for specific tree root can be used standard
SilicaListView. Here is AvailableMapsView.qml
component:
SilicaListView {
id: listView
property AvailableMapsModel originModel
property var rootIndex
signal click(int row, variant item)
model: DelegateModel {
id: visualModel
model: originModel
rootIndex : listView.rootIndex
delegate: ListItem{
property variant myData: model
// ... shortened by entry visuals
onClicked: {
listView.click(index, myData)
}
}
}
}
Downloads.qml page:
AvailableMapsModel{
id: availableMapsModel
}
AvailableMapsView{
id:availableMapListView
originModel:availableMapsModel
onClick: {
var index=availableMapsModel.index(row, /*column*/ 0 /* root as parent */);
if (item.dir){
pageStack.push(Qt.resolvedUrl("MapList.qml"),
{
availableMapsModel: availableMapsModel,
rootDirectoryIndex: index,
rootName: item.name,
downloadsPage: downloadsPage
})
}else{
pageStack.push(Qt.resolvedUrl("MapDetail.qml"),
{
availableMapsModel: availableMapsModel,
mapIndex: index,
mapName: item.name,
mapItem: item,
downloadsPage: downloadsPage
})
}
}
}
And almost the same MapList.qml:
Page {
id: mapListPage
property AvailableMapsModel availableMapsModel
property var rootDirectoryIndex
property string rootName
property var downloadsPage
// ... example shortened by SilicaFlickable, Column, PageHeader ...
AvailableMapsView {
id: availableMapListView
originModel: availableMapsModel
rootIndex: rootDirectoryIndex
onClick: {
var index=availableMapsModel.index(row, /*column*/ 0, /* parent */ rootDirectoryIndex);
if (item.dir){
pageStack.push(Qt.resolvedUrl("MapList.qml"),
{
availableMapsModel: availableMapsModel,
rootDirectoryIndex: index,
rootName: item.name,
downloadsPage: downloadsPage
})
}else{
pageStack.push(Qt.resolvedUrl("MapDetail.qml"),
{
availableMapsModel: availableMapsModel,
mapIndex: index,
mapName: item.name,
mapItem: item,
downloadsPage: downloadsPage
})
}
}
}
}
You can find complete source codes on GitHub. Here is the result: