ListView
in QML has built-in support for sections. In the following example, I have a ListModel where the section is defined via a "sec" role. The ListView
defines a section delegate as well as a contact delegate:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
title: "ListView sections demo"
ListView {
anchors.fill: parent
model: contacts
header: ListViewHeaderDelegate { }
delegate: ListViewDelegate { }
section.property: "sec"
section.delegate: ListViewSectionDelegate { }
}
ListModel {
id: contacts
ListElement { sec: "B"; fn: "Branda"; sn: "Respass" }
ListElement { sec: "C"; fn: "Chana"; sn: "Hollin" }
ListElement { sec: "D"; fn: "Delisa"; sn: "Deak" }
ListElement { sec: "D"; fn: "Demetrius"; sn: "Zona" }
ListElement { sec: "D"; fn: "Dwain"; sn: "Mark" }
}
}
// ListViewHeaderDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Frame {
width: ListView.view.width
background: Rectangle { color: "red" }
RowLayout {
width: parent.width
AppIconButton { icon.source: "address-book-32.svg" }
AppHeadingText { text: qsTr("All Contacts") }
}
}
// ListViewDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Frame {
width: ListView.view.width
RowLayout {
width: parent.width
AppIconButton {
icon.source: "user-32.svg"
icon.color: "green"
}
ColumnLayout {
Layout.fillWidth: true
AppText { text: fn }
AppText { text: qsTr("Full name: %1 %2").arg(fn).arg(sn) }
}
}
}
// ListViewSectionDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Frame {
width: ListView.view.width
background: Rectangle { color: "lightsteelblue" }
RowLayout {
AppHeadingText { text: section }
}
}
// AppIconButton.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item {
id: iconButton
property alias icon: button.icon
Layout.preferredWidth: icon.width
Layout.preferredHeight: icon.height
Button {
id: button
anchors.centerIn: parent
background: Item {}
icon.width: 32
icon.height: 32
icon.color: "white"
}
}
// AppText.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Text {
Layout.fillWidth: true
}
// AppHeadingText.qml
AppText {
color: "white"
}
// address-book-32.svg : https://raw.githubusercontent.com/Esri/calcite-ui-icons/master/icons/address-book-32.svg
// user-32.svg : https://raw.githubusercontent.com/Esri/calcite-ui-icons/master/icons/user-32.svg
You can Try it Online!
QToolBox
looks similar but not very convenient. I would write a proxy model that adds rows for letters and provides appropriate styling for them indata()
implementation. – Tritium