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

Non-looping PathView



  • Hello,

    I need to set up a carousel style picker that can be flicked with touch input:

    0_1564780385953_Screenshot from 2019-08-02 15-05-42.png 0_1564780388991_Screenshot from 2019-08-02 15-06-12.png

    I've been searching all over for solutions and it seems like the two main ways people have done this is with a PathView and a ListView. I put together some tests and I've gotten each of them to almost work the way I want. Unfortunately I need the non-selected numbers to shrink and have reduced opacity which I can do in PathView using PathAtribute, but not in ListView which doesn’t support paths. I also need the selector to stop at the first and last value rather than loop back to the other end (shown in pictures), which ListView can do (and does by default) but which PathView doesn’t seem to have any option for.

    Is there any way to:

    • Stop PathView from looping
    • Smoothly resize and change opacity of ListView elements as they move
    • Or some other way of achieving this type of selector

    Any help would be appreciated, thanks!

    Test QML code showing both options:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window{
        visible: true
        width: 600
        height: 400
    
        // Using PathView
        Rectangle {
            width: 600; height: 200
    
            PathView {
                id: pathv
                anchors.fill: parent
                model: 5
                preferredHighlightBegin: 0.5
                preferredHighlightEnd: 0.5
                highlightRangeMode: PathView.StrictlyEnforceRange
                currentIndex: 3
    
                delegate: Item {
                    width: 130
                    height: 50
                    scale: PathView.textScale
                    opacity: PathView.textOpacity
                    property bool currentItem: PathView.view.currentIndex == index
                    property alias text : textNum.text
                    Text {
                        id: textNum
                        anchors.centerIn: parent
                        font.pixelSize: 36
                        font.bold: currentItem
                        text: (index + 12) * 100
                        color: currentItem ? "black" : "gray"
                    }
                }
    
                path: Path {
                    startX: 100; startY: 100
                    PathAttribute { name: "textScale"; value: 0.3 }
                    PathAttribute { name: "textOpacity"; value: 0.5 }
                    PathLine { x: 300; y: 100}
                    PathAttribute { name: "textScale"; value: 1.0 }
                    PathAttribute { name: "textOpacity"; value: 1.0 }
                    PathLine { x: 500; y: 100}
    
                }
            }
        }
    
        // Using ListView
        Rectangle {
            width: 600; height: 200
            y:200
    
            ListView {
            id: listv
            width: 200; height: 200
            x:250
                model: 5
                preferredHighlightBegin: 0.5
                preferredHighlightEnd: 0.5
                highlightRangeMode: PathView.StrictlyEnforceRange
                currentIndex: 3
                orientation: Qt.Horizontal
    
                delegate: Item {
                    width: 100
                    height: 50
                    property bool currentItem: ListView.view.currentIndex == index
                    property alias text : textNumList.text
                    Text {
                        id: textNumList
                        anchors.centerIn: parent
                        font.pixelSize: 36
                        font.bold: currentItem
                        text: (index + 12) * 100
                        color: currentItem ? "black" : "gray"
                    }
                }
            }
        }
    }
    


  • Hey, I hope this could help.
    I had the same problem, didn't find a built-in solution.

    PathView {
            property int prevIndex: 0
            property int num: 7
            onCurrentIndexChanged: {
                if(currentIndex == 0 || prevIndex == 0){
                    if(dragging) interactive = false;
                    currentIndex = 1;
                }
                else if(currentIndex == num - 1 || prevIndex == num - 1){
                    if(dragging) interactive = false;
                    currentIndex = num - 2;
                }
    
                prevIndex = currentIndex
    
            }
    
    
            onDraggingChanged: {
                if (dragging === false){
                    interactive = true
                }
            }
    
            id: pathv
            width: 600
            height: 200
            model: num
            preferredHighlightBegin: 0.5
            preferredHighlightEnd: 0.5
            highlightRangeMode: PathView.StrictlyEnforceRange
            currentIndex: 3
    
            delegate: Item {
                visible: index !== 0 && index !== (pathv.num - 1)
                width: 130
                height: 50
                scale: PathView.textScale
                opacity: PathView.textOpacity
                property bool currentItem: PathView.view.currentIndex == index
                property alias text : textNum.text
                Text {
                    id: textNum
                    anchors.centerIn: parent
                    font.pixelSize: 36
                    font.bold: currentItem
                    text: (index + 12) * 100
                    color: currentItem ? "black" : "gray"
                }
            }
    
            path: Path {
                startX: 100; startY: 100
                PathAttribute { name: "textScale"; value: 0.3 }
                PathAttribute { name: "textOpacity"; value: 0.5 }
                PathLine { x: 300; y: 100}
                PathAttribute { name: "textScale"; value: 1.0 }
                PathAttribute { name: "textOpacity"; value: 1.0 }
                PathLine { x: 500; y: 100}
    
            }
        }
    

    I used the PathView.
    I added 2 extra items, they are not visible (first and last). When you hit the first /last not visible element it sets you back to the first/last visible element.
    Interactive is turned off (set to false) when you hit that invisible element so you can't over scroll it.
    When dragging is ended ( mouse or finger released, it will become false ) interactive is set back to true.


Log in to reply