4

我正在尝试根据从模型继承的数据动态地重新定义中继器中生成的 QML 对象。

这就像一个魅力 - 一次捕获。第一次生成对象时,在状态的 ParentChange 对象进行更改后,它会自动重新设置为 Repeater 的父级。在 QML 查看器中运行以下 QML 文件,注意控制台消息的顺序以查看我所描述的内容。

单击每个对象后,它们的行为与预期相同。

import QtQuick 1.1

Rectangle {
    id: container
    height: 300
    width: 300

    signal completed

    ListModel {
        id: fooModel
        ListElement { data: "red" }
        ListElement { data: "red" }
        ListElement { data: "blue" }
    }

    Component.onCompleted: {
        console.log("Rect Completed!")
        container.completed()
    }

    // The object I want to dynamically move
    Component {
        id: delg
        Rectangle {
            id: moveable
            height: 40; width: 100
            border.width: 1; border.color: "black"
            state: model.data
            color: state

            // The following code makes it work, but feels very hackish
            /*Connections {
                target: container
                onCompleted: {
                    moveable.parent = moveable.state == "red" ? red_col : blue_col
                }
            }*/

            onStateChanged: { console.log("New state: " + state) }
            onParentChanged: { console.log("New parent: " + parent) }
            Component.onCompleted: { console.log("Delegate Completed!") }


            MouseArea {
                anchors.fill: parent
                onClicked: {
                    // I know this is bad to do, but in my REAL application,
                    // the change is triggered through the model, not the qml
                    // object
                    moveable.state = (moveable.state == "red" ? "blue" : "red")
                }
            }

            states: [
                State {
                    name: 'red'
                    ParentChange { target: moveable; parent: red_col; x: 0 }
                },
                State {
                    name: 'blue'
                    ParentChange { target: moveable; parent: blue_col; x: 0 }
                }
            ]

            transitions: [ Transition {
                    ParentAnimation {
                        NumberAnimation { properties: 'x,y,height,width' }
                    }
            }]
        }
    }

    // Generates the Objects
    Repeater {
        id: repeat
        model: fooModel
        delegate: delg
    }

    // Display
    Row {
        spacing: 100
        Column {
            id: red_col
            spacing: 10
            width: 100; height: 300
            move: Transition { NumberAnimation { properties: "y" } }
            add: Transition { NumberAnimation { properties: "y" } }
        }
        Column {
            id: blue_col
            spacing: 10
            width: 100; height: 300
            move: Transition { NumberAnimation { properties: "y" } }
            add: Transition { NumberAnimation { properties: "y" } }
        }
    }

}

我想出了一种解决这种行为的方法,但它并不漂亮。(有关该修复,请参阅上面注释掉的“连接”代码)。

有没有一种更干净/更简洁的方法来完成我在这里尝试的同样事情?

4

1 回答 1

3

Item简单的方法是在您的代表下放置额外的东西。这将导致RepeaterreparentItem并且您自己的代码将设置其子元素的新父元素,即您的Rectangle元素。像这样:

import QtQuick 1.1
Rectangle {
    id: container
    height: 300
    width: 300

    signal completed

    ListModel {
        id: fooModel
        ListElement { data: "red" }
        ListElement { data: "red" }
        ListElement { data: "blue" }
    }

    Component.onCompleted: {
        console.log("Rect Completed!")
        container.completed()
    }

    // The object I want to dynamically move
    Component {
        id: delg
        Item { 
            Rectangle {
                id: moveable
                height: 40; width: 100
                border.width: 1; border.color: "black"
                state: model.data
                color: state

                // The following code makes it work, but feels very hackish
                /*Connections {
                    target: container
                    onCompleted: {
                        moveable.parent = moveable.state == "red" ? red_col : blue_col
                    }
                }*/

                onStateChanged: { console.log("New state: " + state) }
                onParentChanged: { console.log("New parent: " + parent) }
                Component.onCompleted: { console.log("Delegate Completed!") }


                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        // I know this is bad to do, but in my REAL application,
                        // the change is triggered through the model, not the qml
                        // object
                        moveable.state = (moveable.state == "red" ? "blue" : "red")
                    }
                }

                states: [
                    State {
                        name: 'red'
                        ParentChange { target: moveable; parent: red_col; x: 0 }
                    },
                    State {
                        name: 'blue'
                        ParentChange { target: moveable; parent: blue_col; x: 0 }
                    }
                ]

                transitions: [ Transition {
                        ParentAnimation {
                            NumberAnimation { properties: 'x,y,height,width' }
                        }
                }]
            }
        }
    }

    // Generates the Objects
    Repeater {
        id: repeat
        model: fooModel
        delegate: delg
    }

    // Display
    Row {
        spacing: 100
        Column {
            id: red_col
            spacing: 10
            width: 100; height: 300
            move: Transition { NumberAnimation { properties: "y" } }
            add: Transition { NumberAnimation { properties: "y" } }
        }
        Column {
            id: blue_col
            spacing: 10
            width: 100; height: 300
            move: Transition { NumberAnimation { properties: "y" } }
            add: Transition { NumberAnimation { properties: "y" } }
        }
    }
}
于 2012-05-11T20:03:48.503 回答