Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Add and Delete items in Swipe view on Current index change.



  • Hi,
    I am trying to add and delete elements in Swipe view when ever my current index is changed. initially i load the swipe view with 15 items.
    When ever i swipe to left, am trying to remove an item at the beginning and trying to add an item at the end so that my number of items in my swipe view is maintained with 15 elements.
    I would like to do vise versa(right swiping).
    Im not able to achieve it. Can somebody help.
    Note
    I have to load 10k elements. I Dont want to use loader or Repeater.

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.2
    import QtQuick.Window 2.3
    
    Window {
        visible: true
        width: 500
        height: 400
        title: qsTr("Hello World")
        property int _count:_swipeView.count
        property int  prevIndex: -1
        property Component comp
    
    
    
        SwipeView{
            id:_swipeView
            width: parent.width
            height: parent.height
            currentIndex: 0
    
            onCurrentIndexChanged: {
                console.log("Changing current index and previous "+currentIndex,prevIndex)
                if (prevIndex==-1){
                    console.log("First time access ="+prevIndex + " Current Index="+currentIndex)
                    prevIndex= currentIndex;
                    return
                }
                if (prevIndex<currentIndex){
                    console.log("Moving left PrevIndex="+prevIndex + " Current Index="+currentIndex)
                    removeElementAtBeginning()
                    addElementAtEnd()
                    prevIndex=currentIndex
                    return
                }
                if (prevIndex>currentIndex){
                    console.log("Moving Right PrevIndex="+prevIndex + " Current Index="+currentIndex)
                    addElementAtBeginning()
                    removeElementAtEnd()
                    prevIndex=currentIndex
                    return
                }
    
            }
        }
    
        function createSwipeViewObjects(){
            for(var i=0;i<15;++i){
                comp= Qt.createComponent("SwipeSource.qml")
                var obj=comp.createObject(_swipeView);
                obj.text="Anup "+i
                _swipeView.insertItem(i,obj)
            }
        }
    
        function addElementAtEnd(){
            ++_count
            comp= Qt.createComponent("SwipeSource.qml")
            var obj=comp.createObject(_swipeView);
            obj.text= "Anup "+_count
    
            _swipeView.addItem(obj)
            console.log("current index after adding at end"+_swipeView.currentIndex)
    
        }
    
        function removeElementAtBeginning(){
            _swipeView.takeItem(0)
            console.log("current index after removing at beginning"+_swipeView.currentIndex)
    
        }
    
        function addElementAtBeginning(){
    
            comp= Qt.createComponent("SwipeSource.qml")
            var obj=comp.createObject(_swipeView);
            obj.text="dummy"
            _swipeView.insertItem(0,obj)
            console.log("adding Element At Beginning "+_swipeView.currentIndex)
    
    
        }
    
        function removeElementAtEnd(){
            //  console.log("Dummy Implementation")
    
    
        }
    
    
        Component.onCompleted: {
            createSwipeViewObjects()
    
        }
    }
    
    
    swipeSource.qml
    import QtQuick 2.0
    
    Rectangle{
        width : 300
        height : 400
        color: Qt.rgba(0,0,1,0.5)
        property alias text: t1.text
        Text {
            id:t1
            anchors.centerIn: parent
            font.pixelSize: 30;
            color: "blue"
    
        }
    
        Component.onDestruction: {
            console.log("Destroying..")
        }
    }
    
    
    

  • Moderators

    Swipe view, probably not what you want, but path view should work,

    take this example:

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.12
    
    Window
    {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        color: "green"
        id: win
    
        Rectangle {
            id:root
            anchors.fill: parent
    
    
            function createModel () {
                var model= []
                for(var i=0; i < 255; i++){
                    model.push(Qt.rgba(i/255,i/255,i/255, 255));
                }
                return model;
            }
    
            property var myModel: createModel()
            property int loopIndex: 0
    
            ListModel {
                    id: model
                    ListElement {}
                    ListElement {}
                    ListElement {}
                }
    
                Component {
                    id: delegate
                    Rectangle {
                        id: wrapper
                        width: view.width
                        height: view.height
                        color: root.myModel[root.loopIndex ]
    
                        Text {
                            anchors.centerIn: parent
                            font.pointSize: 26
                            font.bold: true
                            color: "white"
                            text:root.loopIndex
                        }
                    }
                }
    
                Timer {
                    running:  true
                    repeat: true
                    interval: 500
                    onTriggered: view.incrementCurrentIndex()
                }
    
                PathView {
                    id: view
                    anchors.fill: parent
                    snapMode: PathView.SnapOneItem
                    highlightRangeMode: PathView.StrictlyEnforceRange
                    currentIndex: 0
                    property int lastIndex: 0
                    onCurrentIndexChanged: {
                        var dif = currentIndex - lastIndex
                        if(dif == 1 || dif == -2)
                            root.loopIndex ++
                        if(dif == -1 || dif == 2)
                            root.loopIndex--
                        lastIndex = currentIndex
                    }
                    model: model
                    delegate: delegate
                    path: Path {
                        startX: -view.width / 2  // let the first item in left
                        startY: view.height / 2  // item's vertical center is the same as line's
    
                        PathLine {
                            relativeX: view.width * view.model.count  // all items in lines
                            relativeY: 0
                        }
                    }
                }
        }
    }
    
    


  • @J-Hilk Thank you. it works !!:) but there is a bug.
    The item at the 0th and last index keeps rotating, i.e swipe has to stop once we reach end or come to starting index. is there a way to stop it.?


  • Moderators

    @Anup-deshpande just a matter of catching the edge cases I believe.

    My above example can be adjusted with the following change to the onCurrentIndexChanged behavior :

    onCurrentIndexChanged: {
                        var dif = currentIndex - lastIndex
                        if(dif == 1 || dif == -2){
                            if(root.loopIndex == root.myModel.length -1)
                                root.loopIndex = 0
                            else
                                root.loopIndex ++
                        }
                        if(dif == -1 || dif == 2){
                            if(root.loopIndex == 0)
                                root.loopIndex = root.myModel.length -1
                            else
                                root.loopIndex--
                        }
                        lastIndex = currentIndex
                    }
    

Log in to reply