Bibin
Bibin

Reputation: 463

How to create custom scrollbar for TableView in QML?

I want to customize the ScrollBar in a TableView.
I am able to customize the ScrollBar in ListView and GridView but I couldn't do the same with the TableView.

I found that this is because GridView and ListView inherit from the Flickable but TableView inherits from ScrollView. Is there any alternative for this?

TableView {
    id:songGrid
    TableViewColumn {
        role: "title"
        title: "Title"
        width: 100
    }
    TableViewColumn {
        role: "author"
        title: "Author"
        width: 200
    }


    ScrollBar.horizontal:  ScrollBar {
        id: scrollBar2
        anchors.bottom:  songGrid.bottom
        //            anchors.bottomMargin: 70*downscaleFactor
        width: 5
        active: true
        visible:songGrid.moving?true:false

        contentItem: Rectangle {
            id:contentItem_rect2
            width:100
            implicitHeight:4
            radius: implicitHeight/2
            color: "Red"
        }
    }

    model: libraryModel1
}


ListModel {
    id: libraryModel1
    ListElement {
        title: "A Masterpiece"
        author: "Gabriel"
    }
    ListElement {
        title: "Brilliance"
        author: "Jens"
    }
    ListElement {
        title: "Outstanding"
        author: "Frederik"
    }
}

Upvotes: 6

Views: 8682

Answers (2)

H.C.Liu
H.C.Liu

Reputation: 166

You can use Qt Quick Controls Styles QML Types to change the appearance of scrollbar.

TableView has an style attribute inherit from ScrollView. To customize the scrollbar, just override it.

Here is a simple example.

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

TableView {
    id: songGrid
    TableViewColumn {
        role: "title"
        title: "Title"
        width: 100
    }
    TableViewColumn {
        role: "author"
        title: "Author"
        width: 200
    }
    model: libraryModel1
    style: TableViewStyle {
        handle: Rectangle {
            implicitHeight: 17
            color: "red"
        }
    }

    ListModel {
        id: libraryModel1
        ListElement {
            title: "A Masterpiece"
            author: "Gabriel"
        }
        ListElement {
            title: "Brilliance"
            author: "Jens"
        }
        ListElement {
            title: "Outstanding"
            author: "Frederik"
        }
    }
}

You can also change the background of scorllbar, appearance of increment/decrement button... etc. For more information, please refer to ScrollViewStyle QML Type(The parent class of TableViewStyle)

BTW, if you want to create a new scrollbar as derM said, you can set horizontalScrollBarPolicy or verticalScrollBarPolicy to Qt.ScrollBarAlwaysOff to disable default scrollbar.These two property were both from ScrollView

Upvotes: 2

derM
derM

Reputation: 13691

You can just create a ScrollBar, put it where ever you want. Then you bind the songGrid.flickableItem.contentX/Y to the ScrollBar.position in the correct way. If the TableView can be moved by other means then the ScrollBar you need to use a second Binding to update the position in those cases.

This is a short sketch-up in which I only account for the direction: ScrollBar -> TableView (add it to the code from your Question).

Binding {
    target: songGrid.flickableItem
    property: "contentY"
    value: (songGrid.flickableItem.contentHeight + 16) * vbar.position - (16 * (1 - vbar.position))
}

ScrollBar {
    id: vbar
    z: 100
    orientation: Qt.Vertical
    anchors.top: songGrid.top
    anchors.left: songGrid.right
    anchors.bottom: songGrid.bottom
    active: true
    contentItem: Rectangle {
        id:contentItem_rect2
        radius: implicitHeight/2
        color: "Red"
        width: 10 // This will be overridden by the width of the scrollbar
        height: 10 // This will be overridden based on the size of the scrollbar
    }
    size: (songGrid.height) / (songGrid.flickableItem.contentItem.height)
    width: 10
}

You can see those mysterious 16 in the Binding. This is some offset that is needed, probably to account for the horizontal ScrollBar. This might be different for different styles/platforms.

If you have further questions, please ask a new question. If you only need more clarification, place a comment.

Upvotes: 3

Related Questions