Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Non-looping PathView
Forum Update on Monday, May 27th 2025

Non-looping PathView

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 3 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    khislop
    wrote on last edited by khislop
    #1

    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"
                    }
                }
            }
        }
    }
    
    1 Reply Last reply
    0
    • PeTroVicP Offline
      PeTroVicP Offline
      PeTroVic
      wrote on last edited by
      #2

      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.

      MarkkyboyM 1 Reply Last reply
      2
      • PeTroVicP PeTroVic

        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.

        MarkkyboyM Offline
        MarkkyboyM Offline
        Markkyboy
        wrote on last edited by
        #3

        @PeTroVic said in Non-looping PathView:

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

        Spot on!, just what I was looking for here in 2023!, kudos!, I've not found any other answers to this query.

        Don't just sit there standing around, pick up a shovel and sweep up!

        I live by the sea, not in it.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved