Reputation: 16685
I am unable to implement listview with sections. I've successfully repeated an example from Qt
documentation but there is ListModel
used which works okay, but not a var
.
How it works with example:
ListView {
width: 100
height: 100
id: listview
model: ListModel {
id: animalsModel
ListElement { name: "Ant"; size: "Tiny" }
ListElement { name: "Flea"; size: "Tiny" }
ListElement { name: "Parrot"; size: "Small" }
ListElement { name: "Guinea pig"; size: "Small" }
ListElement { name: "Rat"; size: "Small" }
ListElement { name: "Butterfly"; size: "Small" }
ListElement { name: "Dog"; size: "Medium" }
ListElement { name: "Cat"; size: "Medium" }
ListElement { name: "Pony"; size: "Medium" }
ListElement { name: "Koala"; size: "Medium" }
ListElement { name: "Horse"; size: "Large" }
ListElement { name: "Tiger"; size: "Large" }
ListElement { name: "Giraffe"; size: "Large" }
ListElement { name: "Elephant"; size: "Huge" }
ListElement { name: "Whale"; size: "Huge" }
}
delegate: Text { text: name; font.pixelSize: 18 }
section.property: "size"
section.criteria: ViewSection.FullString
section.delegate: Component {
id: sectionHeading
Rectangle {
width: container.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20
}
}
}
}
But when I try to use some model from the code (in my case it is a QVariant
from PyQt5
) it does not work at all:
ListView {
width: 100
height: 100
id: listview
property var m: [
{
name: "Animal",
size: "Big"
},
{
name: "Dog",
size: "Small"
},
{
name: "Cat",
size: "Small"
}
]
model: m
delegate: Text { text: modelData.name; font.pixelSize: 18 }
section.property: "modelData.size"
section.criteria: ViewSection.FullString
section.delegate: Component {
id: sectionHeading
Rectangle {
width: container.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20
}
}
}
}
The reason I choose var
here because there is not any other method to receive a model from Python , so any list
or map
from python
needs to be wrapped as QVariant
.
Upvotes: 3
Views: 2724
Reputation: 25871
There were a couple of issues with your code snippet:
section.property: "size"
(not section:property: "modelData.size"
)font.pointSize: 14
instead of (font.pixelSize: 20
)
width: 100
and height: 100
with anchors.fill: parent
.
Frame
and ListView.view.width
for sizing delegates
Frame
gives a padded border to componentsScrollBar.vertical
Here's a full working example:
import QtQuick
import QtQuick.Controls
Page {
ListView {
anchors.fill: parent
model:[
{ name: "Animal", size: "Big" },
{ name: "Dog", size: "Small" },
{ name: "Cat", size: "Small" }
]
delegate: Frame {
width: ListView.view.width - 20
Text {
text: modelData.name
font.pointSize: 12
}
}
section.property: "size"
section.delegate: Frame {
width: ListView.view.width - 20
background: Rectangle { color: "lightsteelblue" }
Text {
text: section
font.bold: true
font.pointSize: 14
}
}
ScrollBar.vertical: ScrollBar {
width: 20
policy: ScrollBar.AlwaysOn
}
}
}
You can Try it Online!
Upvotes: 0
Reputation: 12854
From Qt documentation:
model : model
This property holds the model providing data for the list.
The model provides the set of data that is used to create the items in the view. Models can be created directly in QML using ListModel, XmlListModel or VisualItemModel, or provided by C++ model classes. If a C++ model class is used, it must be a subclass of QAbstractItemModel or a simple list.
So you cannot provide an array as a model, it should be one of the objects above. You can create such model and access it from Python code to add/remove items.
ListView {
width: 100
height: 100
id: listview
delegate: Text { text: name; font.pixelSize: 18 }
model: ListModel { id: listModel }
section.property: "size"
section.criteria: ViewSection.FullString
section.delegate: Component {
id: sectionHeading
Rectangle {
width: container.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20
}
}
}
function callFromPython {
listModel.append({name: "Animal",size: "Big"});
listModel.append({name: "Dog",size: "Small"});
listModel.append({name: "Cat",size: "Small"});
}
}
Upvotes: 3