How I can use different delegates in qml for the ListView. For example I have QList<SomeObject*> list, SomeObject has two fields: type (circle, rectangle, etc), and someValue. I created QListModel for this list. I have different qml elements (circle.qml, rectangle.qml, etc). How can I view delegate for an item by type, and view field someValue in this delegate. And can I position these delegates without a table/list, I wanted to position them by coordinates(x, y).
CodePudding user response:
- You can try a concept of qml Loader that may match your requirements. Basically, you cannot define multiple delegates for a single view. So setting your Top Delegate as the loader and loading the items based on the type will help you with this case.
- Positioning is also possible you can have x & y pos defined with your model data. So that you can align your view items accordingly. I have used Scrollview Repeater in this case
Shared a minimal sample here. For sake of simplicity, I have kept my data with Qml ListModel. The same can be done with objects from the c model as well. Here provided the source as a Qt solution project too.
// ShapeModel.qml //
import QtQuick 2.15
import QtQml.Models 2.15
ListModel {
ListElement {
type: "circle"
val: "100"
xpos: 10
ypos: 10
}
ListElement {
type: "rectangle"
val: "30"
xpos: 100
ypos: 100
}
ListElement {
type: "circle"
val: "150"
xpos: 300
ypos: 450
}
ListElement {
type: "rectangle"
val: "20"
xpos: 500
ypos: 200
}
ListElement {
type: "circle"
val: "25"
xpos: 650
ypos: 100
}
ListElement {
type: "rectangle"
val: "60"
xpos: 600
ypos: 200
}
}
// main.qml //
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Qt MVC")
Component {
id: componentCircleId
Rectangle {
border.color: "blue"
border.width: 1
height: value
width: value
radius: value/2
}
}
Component {
id: componentRectangleId
Rectangle {
border.color: "orange"
border.width: 1
height: value
width: value
}
}
Component {
id: componentLoaderId
Loader {
property real value: val
x: xpos
y: ypos
sourceComponent: type === "circle" ?
componentCircleId : componentRectangleId
}
}
ScrollView {
id: scrollviewId
anchors.fill: parent
Repeater {
anchors.fill: parent
model: ShapeModel{}
delegate: componentLoaderId
onItemAdded: {
// scroll area computation
// Better solutions may be available
if(item.x item.width > scrollviewId.contentWidth)
scrollviewId.contentWidth = item.x item.width
if(item.y item.height > scrollviewId.contentHeight)
scrollviewId.contentHeight = item.y item.height
}
}
}
}