首页 文章

QML DelegateModel:从委托访问DelegateModel

提问于
浏览
1

我正在尝试使用不同的委托和拖放功能创建一个ListView . 代表应装载装载机 .

QML文档为没有Loader的ListView提供了一个工作示例:http://doc.qt.io/qt-5/qtquick-tutorials-dynamicview-dynamicview3-example.html

但是,使用Loader我得到错误:无法读取未定义的属性'DelegateModel'

我不明白如何从Loader访问DelegateModel .

我们非常感谢您对该解决方案的暗示!

main.qml:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.1
import QtQml.Models 2.3

Window {
    id: mainroot

    visible: true
    width: 640
    height: 480

    Rectangle{
        id:viewContainer

        anchors.fill: parent

        DelegateModel {
            id: visualModel

            model: ListModel{
                id:m_model

                ListElement{
                    type:1
                    m_text :"Text1"
                }

                ListElement{
                    type:1
                    m_text :"Text2"
                }
            }

            delegate:        Loader{
                id:idLoader

                width: view.width
                height: childrenRect.height

                Component.onCompleted: {
                    switch(type){
                    case 1:
                        idLoader.setSource("TestDelegate.qml", {"m_text": m_text})
                        break;
                    }
                }
            }
        }

        ListView{
            id: view

            anchors.fill: parent
            spacing: 5

            model: visualModel
        }
    }
}

TestDelegate.qml:

import QtQuick 2.7

MouseArea {
    id: dragArea

    property bool held: false
    property string m_text

    anchors { left: parent.left; right: parent.right }
    height: 50
    width: view.width

    drag.target: held ? content : undefined
    drag.axis: Drag.YAxis

    onPressAndHold: held = true
    onReleased: held = false

    Rectangle {
        id: content

        anchors {
            horizontalCenter: parent.horizontalCenter
            verticalCenter: parent.verticalCenter
        }
        width: dragArea.width
        height: textfield.implicitHeight


        Drag.active: dragArea.held
        Drag.source: dragArea
        Drag.hotSpot.x: width / 2
        Drag.hotSpot.y: height / 2

        border.width: 1
        border.color: "lightsteelblue"
        color: dragArea.held ? "lightsteelblue" : "white"
        Behavior on color { ColorAnimation { duration: 100 } }
        radius: 2
        states: State {
            when: dragArea.held

            ParentChange { target: content; parent: viewContainer }
            AnchorChanges {
                target: content
                anchors { horizontalCenter: undefined; verticalCenter: undefined }
            }
        }

        Text{
            id: textfield

            anchors.centerIn: parent
            text: m_text
        }

    }
    DropArea {
        anchors { fill: parent; margins: 10 }

        onEntered: {
            visualModel.items.move(
                    idLoader.item.drag.source.DelegateModel.itemsIndex,
                    idLoader.item.dragArea.DelegateModel.itemsIndex)
        }
    }
}

1 回答

  • 0

    在使用Loader加载的文件中定义的项目或者通常与导入的任何其他.qml文件一起定义的项目不应直接依赖于主文件,因为ID具有作用域,因此最好公开属性,在您的情况下:

    ╭------------------------------------------╮
    |                   bool held        ------┿--->
    |  TestDelegate     string m_text    ------┿--->
    |  ============     DelegateModel md ------┿--->
    |                   int index        ------┿--->
    ╰------------------------------------------╯
    

    考虑到上述情况,解决方案如下:

    main.qml

    import QtQuick 2.7
    import QtQuick.Window 2.0
    import QtQml.Models 2.3
    
    Window {
        id: mainroot
        visible: true
        width: 640
        height: 480
    
        Rectangle{
            id:viewContainer
            anchors.fill: parent
    
            DelegateModel {
                id: visualModel
                model: ListModel{
                    id:m_model
                    Component.onCompleted: {
                        for(var i=0; i< 40; i++){
                            m_model.append({"type": 1, "m_text": "Text" + i})
                        }
                    }
                }
                delegate:
                    Loader{
                    id: idLoader
                    width: view.width
                    height: childrenRect.height
                    property int index: DelegateModel.itemsIndex
                    onIndexChanged: if(status == Loader.Ready) idLoader.item.index = index
                    Component.onCompleted: {
                        switch(type){
                        case 1:
                            idLoader.setSource("TestDelegate.qml", {
                                                   "m_text": m_text,
                                                   "index": index,
                                                   "md": visualModel
                                               })
                            break;
                        }
                    }
                }
            }
            ListView{
                id: view
                anchors.fill: parent
                spacing: 5
                model: visualModel
            }
        }
    }
    

    TestDelegate.qml

    import QtQuick 2.7
    import QtQml.Models 2.3
    
    MouseArea {
        id: dragArea
        property bool held: false
        property string m_text
        property DelegateModel md: null
        property int index : -1;
        anchors { left: parent.left; right: parent.right }
        height: 50
        width: view.width
        drag.target: held ? content : undefined
        drag.axis: Drag.YAxis
        onPressAndHold: held = true
        onReleased: held = false
        Rectangle {
            id: content
            anchors {
                horizontalCenter: parent.horizontalCenter
                verticalCenter: parent.verticalCenter
            }
            width: dragArea.width
            height: textfield.implicitHeight
            Drag.active: dragArea.held
            Drag.source: dragArea
            Drag.hotSpot.x: width / 2
            Drag.hotSpot.y: height / 2
            border.width: 1
            border.color: "lightsteelblue"
            color: dragArea.held ? "lightsteelblue" : "white"
            Behavior on color { ColorAnimation { duration: 100 } }
            radius: 2
            states: State {
                when: dragArea.held
                ParentChange { target: content; parent: viewContainer }
                AnchorChanges {
                    target: content
                    anchors { horizontalCenter: undefined; verticalCenter: undefined }
                }
            }
            Text{
                id: textfield
                anchors.centerIn: parent
                text: m_text
            }
        }
        DropArea {
            anchors { fill: parent; margins: 10 }
            onEntered: {
                if(md !== null)
                    md.items.move(drag.source.index, dragArea.index)
            }
        }
    }
    

相关问题