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: