如何在qml中通过Repeater填充网格时跳过绘制项目?

时间:2017-04-11 15:48:12

标签: qml

我想用一个Repeater填充一个Grid,但不是所有的单元都应该得到一个Item。怎么做?

Rectangle {
    id: base

    Grid {
        id: grid
        anchors.fill: parent
        columns: 30
        rows: 20

        Repeater {
            model: grid.columns * grid.rows
            delegate: Item {
                // How to skip this at row 5, column 3, for example
                width: grid.width / grid.columns
                height: grid.height / grid.rows
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这基本上是同一个问题,因为如何在Repeater中根据模型的数据使用特殊情况下具有不同的委托:委托是空的

对于这种更通用的方法,您可以使用如下动态对象创建:     窗口{         id:root         可见:是的         宽度:400;身高:400

    // delegate 0 is skipped, 1 is circle, 2 is quadrangle
    ListModel {
        id: lm
        ListElement { delegate: 0 }
        ListElement { delegate: 1; color: 'red' }
        ListElement { delegate: 2; color: 'green' }
        ListElement { delegate: 1; color: 'blue' }
        ListElement { delegate: 0 }
        ListElement { delegate: 0 }
        ListElement { delegate: 1; color: 'orchid' }
        ListElement { delegate: 0 }
        ListElement { delegate: 1; color: 'red' }
        ListElement { delegate: 2; color: 'green' }
        ListElement { delegate: 1; color: 'blue' }
        ListElement { delegate: 0 }
        ListElement { delegate: 0 }
        ListElement { delegate: 1; color: 'orchid' }
    }


    Grid {
        anchors.fill: parent
        columns: 5
        Repeater {
            id: rep
            property var delegates: [function() { console.log('skipped'); return null }, circ.createObject, rect.createObject ]
            model: lm
            delegate: Item {
                width: (delegate ? delegate.width : 1)
                height: (delegate ? delegate.height : 1)
                property var delegate: rep.delegates[model.delegate](this, { color: model.color })
            }
        }
    }


    Component {
        id: circ
        Rectangle {
            width: 20
            height: 20
            radius: 10
        }
    }

    Component {
        id: rect
        Rectangle {
            width: 20
            height: 20
        }
    }
}

当然,您可以使用任何cirterium和方法进行选择,无论是否应使用代表。在很多情况下,ListModel和函数列表似乎很方便。您也可以使用switch语句或其他任何内容。

您可以使用JS作为顶级元素,而不是使用Loader - 函数,并设置或不设置源。您只需确保顶层委托具有尺寸(至少宽度和高度为1),否则定位器(Grid/Column/Row)将忽略它们的存在。

动态创建的优点是,如果委托是复杂的,它将不会被创建,只是变得不可见,就像 Tony Clifton

的解决方案一样

答案 1 :(得分:0)

你真的不能跳过"代表的创作。您可以使用索引来确定要隐藏的项目。如果你想要一个空的"网格中的间隙将不透明度设置为0.如果你想要它"完全"走了,设置为假。

 Repeater {
        model: grid.columns * grid.rows
        delegate: Rectangle {
            // How to skip this at row 5, column 3
            // 4 * columns + 2 = 122   // 4 & 3 because of zero based counting.
            color: "red"
            opacity: index !== 122 ? 1 : 0
            width: (grid.width / grid.columns) - 1
            height: (grid.height / grid.rows) - 1
            Text {
                anchors.centerIn: parent
                text: index
            }
        }
    }