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

Scrollable Button Grid



  • Rather new to QML and have come up with an idea I want to implement but am having trouble. So I am looking to create a vertically scrollable set of buttons. I will basically have a row column setup with a few buttons across and several high. The user should be able to scroll vertically through this list.

    Here is the catch, whichever row of buttons is closest to the center of the screen/list should snap into place. Essentially, imagine a "Tumbler" type component, but rather than having a list of numbers or text items there would be rows of buttons. This is why something like a "Flickable" won't work, as it doesn't snap to any one position but rather stops wherever the user stops moving it.

    I am thinking a Tumbler component would actually work for this, but not sure how to implement it because I don't quite understand the whole model/delegate thing yet.

    If this helps, imagine I have a grid of buttons on my screen like this:

       Grid {
           columns: 3
           rows: 3
           columnSpacing: 10
           rowSpacing: 10
    
    // row 1
           Button { width: 100; height: 50; text: "btn1" }
           Button { width: 100; height: 50; text: "btn2" }
           Button { width: 100; height: 50; text: "btn3" }
    
    // row 2
           Button { width: 100; height: 50; text: "btn4" }
           Button { width: 100; height: 50; text: "btn5" }
           Button { width: 100; height: 50; text: "btn6" }
    
    // row 3
           Button { width: 100; height: 50; text: "btn7" }
           Button { width: 100; height: 50; text: "btn8" }
           Button { width: 100; height: 50; text: "btn9" }
       }
    

    But they won't all fit on the screen at the same time, so I want the user to be able to scroll through them with the "selected" row snapping into place just like number items in a tumbler. Make sense?

    Any help or tips would be appreciated. Thanks!



  • Bump....



  • Hi,

    first important question is: Do you want a tumbler?

    Because a tumbler is like a wheel, so you cannot scroll to an end, it will start from the beginning again if you have scrolled to the last item ... it's a loop.
    The rest is a matter of styling.

    So a tumbler has two important properties: model and delgate.
    The model says, what should be displayed (the data). In your case this might be the number of rows and the text of the button.
    The delgates tells the tumbler how to the data should be displayed. So for example as 3 buttons in a row, where the row closest to the center should snap into place.
    So the look of the tumbler (so that it's only a number and have this snapping effect is just the default value and can therefore be looked up for inspiration).
    https://github.com/qt/qtquickcontrols2/blob/5.11/src/imports/controls/Tumbler.qml

    delegate: Text {
            text: modelData
            color: control.visualFocus ? control.palette.highlight : control.palette.text
            font: control.font
            opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
    }
    

    As you can see the snapping effect is created through changing the opacity of elements, which are not centered at the moment. So in your case change the delgate to a Row with 3 Buttons and add the opacity effect. You can also apply a scale effect if you want to.

    The model can be for the beginning just a number, which is then the number of rows. But you can later change this to a more complicated model having individual texts and actions for each button.
    See: http://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html#qml-data-models

    If you don't want a tumbler, please use a GridView or a ListView or a repeater. With the first to recommendations you are more flexible with changing the color or text of the buttons. A tumbler works like a ListView, so you can still you my explanation above.


Log in to reply