Home > OS >  Qml c diffrent delegates qt mvc
Qml c diffrent delegates qt mvc

Time:10-26

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:

To have different delegates based on a role (it can also be done depending on the row or column), you should use DelegateChooser with DelegateChoice:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import Qt.labs.qmlmodels 1.0

Window {
    width: 640
    height: 480
    visible: true

    ListModel {
        id: shapeModel
        ListElement {
            type: "circle"
            value: 100
            x: 10
            y: 10
        }
        ListElement {
            type: "rectangle"
            value: 30
            x: 100
            y: 100
        }
        ListElement {
            type: "circle"
            value: 30
            x: 300
            y: 450
        }
        ListElement {
            type: "rectangle"
            value: 20
            x: 500
            y: 200
        }
        ListElement {
            type: "circle"
            value: 25
            x: 650
            y: 100
        }
        ListElement {
            type: "rectangle"
            value: 60
            x: 600
            y: 200
        }
    }

    Flickable {
        anchors.fill: parent
        contentWidth: contentItem.childrenRect.width
        contentHeight: contentItem.childrenRect.height
        Repeater {
            model: shapeModel
            delegate: DelegateChooser {
                role: "type"
                DelegateChoice {
                    roleValue: "rectangle"
                    Rectangle {
                        x: model.x
                        y: model.y
                        height: model.value
                        width: model.value
                        border.color: "orange"
                        border.width: 1
                    }
                }
                DelegateChoice {
                    roleValue: "circle"
                    Rectangle {
                        x: model.x
                        y: model.y
                        height: model.value
                        width: model.value
                        radius: model.value/2
                        border.color: "blue"
                        border.width: 1
                    }
                }
            }
        }
    }
}

It avoids the additional indirection of a Loader.

CodePudding user response:

  1. 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.
  2. 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
            }
        }
    }
}

  • Related