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

Listview with custom scrollbars



  • Dear All, before to post my question here, I've tried to looking for the same problem on Google, without luck.

    My boss has requested that my listview with delegate doesn't have classic scrollbars, but it shows 3 dots on top and bottom that act like indicator that the user has items to scroll.

    With a simple picture:

    ...
    Item_1
    Item_2
    Item_n
    ...

    All in all, a sort of custom scrollbar.

    I was thinking that if I can get a property with the count of the items fully visible into the viewport I can do it.

    Is ScrollIndicator (to be customized) a good idea?
    Any suggestion where I can read something to address a solution ?

    Thank you
    Cristiano


  • Moderators

    ListView has header and footer properties, I think you could abuse them for this - if not, just add a Text item above and below the ListView. I don't think reimplementing ScrollBar will help here at all.



  • I've solved.

    The snippet is here. Is a part of a whole QML file with a C++ backend, but is quite straightforward and maybe can be useful for somebody that want to do the same:

    Column
        {
            anchors.fill: parent
            // header
            Rectangle
            {
                id: headerComponent
                width: list.width
                height: headerHeight
                color: "transparent"
    
                Text {
                    anchors.fill: parent
                    color: "white"
                    visible: list.dotUp
                    font.pointSize: 11
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    text: qsTr("...")
                }
            }
    
            ListView
            {
                id: list
                property int draggedItem: -1
                property int visibileItems: 0
                property bool dotUp: false
                property bool dotDown: false
    
                width: parent.width
                height: parent.height - headerHeight*2
                clip: true
                spacing: 5
                model: backendList.model
                highlightMoveDuration: 10
                focus: true
                currentIndex: backendList.currentIndex
                snapMode: ListView.SnapToItem
                pixelAligned: true
    
                function setHeaderAndFooter()
                {     
                    if (visibileItems >= count)
                    {
                        return
                    }
                    var index = indexAt(1, contentY)
                    if ( index === 0 && visibileItems < count)
                    {
                        dotDown = true
                        dotUp = false
                    }
    
                    if (index > 0 && !(count-index <= visibileItems))
                    {
                        dotDown = true
                        dotUp = true
                    }
    
                    if (index > 0 && count-index <= visibileItems)
                    {
                        dotDown = false
                        dotUp = true
                    }
                }
    
                onCountChanged:
                {
                    visibileItems =  height / ( backendList.itemHeight + list.spacing)
                    var reminder =  height % ( backendList.itemHeight + list.spacing)
                    if (reminder)
                    {
                        ++visibileItems
                    }
    
                    setHeaderAndFooter()
                }
    
                onContentYChanged:
                {
                    var index = indexAt(1, contentY)
                    setHeaderAndFooter()
                }
    .....
            // footer
            Rectangle
            {
                width: list.width
                height: headerHeight
                color: "transparent"
    
                Text {
                    anchors.fill: parent
                    color: "white"
                    font.pointSize: 11
                    visible: list.dotDown
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    text: qsTr("...")
                }
            }
    

    Regards
    Cristiano


  • Moderators

    thanks for sharing!


Log in to reply