Qml c++ 不同的代表 qt mvc

Qml c++ diffrent delegates qt mvc

我如何在 qml 中为 ListView 使用不同的委托。例如,我有 QList 列表,SomeObject 有两个字段:类型(圆形、矩形等)和 someValue。我为此列表创建了 QListModel。我有不同的 qml 元素(circle.qml、rectangle.qml 等)。如何按类型查看项目的委托,并查看此委托中的字段 someValue。我可以在没有 table/list 的情况下定位这些代表吗?我想按坐标(x,y)定位它们。

  1. 您可以尝试一个可能符合您要求的qml Loader概念。基本上,您不能为单个视图定义多个委托。因此,将您的 Top Delegate 设置为加载程序并根据类型加载项目将帮助您解决这种情况。
  2. 也可以定位,您可以使用模型数据定义 x 和 y 位置。这样您就可以相应地对齐视图项。我在这种情况下使用了 Scrollview + Repeater

在此处共享了一个最小示例。为了简单起见,我将数据保存在 Qml ListModel 中。也可以对来自 c++ 模型的对象进行同样的操作。 Here 也将源作为 Qt 解决方案项目提供。

// 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
            }
        }
    }
}

要根据角色有不同的代表(也可以根据行或列来完成),您应该使用 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
                    }
                }
            }
        }
    }
}

它避免了加载程序的额外间接。