禁用在SwipeDelegate上滑动多个项目

时间:2017-09-25 06:46:58

标签: qt qml qtquickcontrols2

默认情况下,SwipeDelegate允许滑动多个项目,如下图所示:

enter image description here

正如您所看到的,多次滑动项目一次打开,我一次只想要一个打开的项目,这意味着如果您打开项目#1,通过打开项目#2,项目#1应该关闭。我怎么能做到这一点?

使用SwipeDelegate的ListView的示例代码:

ListView {
    id: listView
    anchors.fill: parent

    delegate: SwipeDelegate {
        id: delegate

        text: modelData
        width: parent.width

        swipe.right: Rectangle {
            width: parent.width
            height: parent.height

            Label {
                text: qsTr("SOME ACTION BUTTON")

                padding: 20
                anchors.fill: parent
            }

        }
    }

    model: ListModel {
        id: listModel
        ListElement { text: "Lorem ipsum dolor sit amet" }
        ListElement { text: "Curabitur sit amet risus" }
        ListElement { text: "Suspendisse vehicula nisi" }
        ListElement { text: "Mauris imperdiet libero" }
        ListElement { text: "Sed vitae dui aliquet augue" }
        ListElement { text: "Praesent in elit eu nulla" }
        ListElement { text: "Etiam vitae magna" }
        ListElement { text: "Pellentesque eget elit euismod" }
        ListElement { text: "Nulla at enim porta" }
        ListElement { text: "Fusce tincidunt odio" }
        ListElement { text: "Ut non ex a ligula molestie" }
        ListElement { text: "Nam vitae justo scelerisque" }
        ListElement { text: "Vestibulum pulvinar tellus" }
        ListElement { text: "Quisque dignissim leo sed gravida" }
    }


    ScrollIndicator.vertical: ScrollIndicator { }
}

2 个答案:

答案 0 :(得分:5)

我将如何做到这一点:

import QtQuick 2.9
import QtQuick.Controls 2.3
import QtGraphicalEffects 1.0

ApplicationWindow {
    id: window
    width: 800
    height: 600
    visible: true

    ListView {
        id: listView
        anchors.fill: parent

        ButtonGroup {
            buttons: listView.contentItem.children
        }

        delegate: SwipeDelegate {
            id: delegate

            checkable: true
            text: modelData
            width: parent.width
            checked: swipe.complete
            onCheckedChanged: if (!checked) swipe.close()

            swipe.right: Rectangle {
                width: parent.width
                height: parent.height
                color: "#666"

                Label {
                    text: qsTr("SOME ACTION BUTTON")
                    color: "white"
                    leftPadding: 20
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }

        model: ListModel {
            id: listModel
            ListElement { text: "Lorem ipsum dolor sit amet" }
            ListElement { text: "Curabitur sit amet risus" }
            ListElement { text: "Suspendisse vehicula nisi" }
            ListElement { text: "Mauris imperdiet libero" }
            ListElement { text: "Sed vitae dui aliquet augue" }
            ListElement { text: "Praesent in elit eu nulla" }
            ListElement { text: "Etiam vitae magna" }
            ListElement { text: "Pellentesque eget elit euismod" }
            ListElement { text: "Nulla at enim porta" }
            ListElement { text: "Fusce tincidunt odio" }
            ListElement { text: "Ut non ex a ligula molestie" }
            ListElement { text: "Nam vitae justo scelerisque" }
            ListElement { text: "Vestibulum pulvinar tellus" }
            ListElement { text: "Quisque dignissim leo sed gravida" }
        }


        ScrollIndicator.vertical: ScrollIndicator { }
    }
}

ButtonGroup确保只有一个"按钮" (SwipeDelegate派生自AbstractButton)可以一次检查。 SwipeDelegate没有视觉效果来表示已检查状态,因此我们可以安全地使用它来跟踪哪一个应该打开。我们仍然需要关闭以前打开的委托,以便

onCheckedChanged: if (!checked) swipe.close()

进来了。

swipedelegate

答案 1 :(得分:0)

受ButtonGroup答案的启发,这是我的解决方案,不需要修改委托:

SwipeDelegateGroup.qml

import QtQuick 2.9
import QtQuick.Controls 2.2

Item {
    id: swipeGroup

    property ListView listView: parent
    QtObject {
        id: d
        property var delegates: swipeGroup.listView.contentItem.children
        property var delegateCache: []

        onDelegatesChanged: {
            for (var i = 0; i < d.delegates.length; i++) {
                var thisItem = d.delegates[i];
                if (!thisItem.hasOwnProperty("swipe")) {
                    continue;
                }
                if (d.delegateCache.indexOf(thisItem) < 0) {
                    d.delegateCache.push(thisItem);

                    thisItem.Component.destruction.connect(function() {
                        d.delegateCache.splice(d.delegateCache.indexOf(thisItem), 1)
                    })

                    thisItem.swipe.opened.connect(function() {
                        for (var j = 0; j < d.delegates.length; j++) {
                            var otherItem = d.delegates[j];
                            if (thisItem === otherItem) {
                                continue;
                            }
                            if (!otherItem.hasOwnProperty("swipe")) {
                                continue;
                            }
                            otherItem.swipe.close();
                        }
                    })
                }
            }
        }
    }
}

然后将其像这样放入ListView中:

ListView {

    SwipeDelegateGroup {}

    delegate: SwipeDelegate {
        ...
    }
}