Qml flickable disable scroll inertia
-
wrote on 6 Jun 2017, 18:34 last edited by
I want to make a flickable-listview to be only scrollable via the mouse wheel or up/down buttons on the scrollbar. I would also like to disable the scroll momentum/inertia that the flickable has so it behaves properly when scrolling in big lists with the scroll wheel and doesn't feel like a touch device.
-
wrote on 6 Jun 2017, 20:20 last edited by
Hi!
MyListView.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 Rectangle { id: myListView clip: true focus: true property var model: null property int moveSpeed: 300 function moveContent(up) { listView.flick(0, up ? moveSpeed : -moveSpeed ) } ListView { id: listView anchors.fill: parent model: myListView.model delegate: Text { text: number + ": " + name } boundsBehavior: Flickable.StopAtBounds } MouseArea { anchors.fill: parent onWheel: myListView.moveContent( wheel.angleDelta.y>0 ) } Keys.onPressed: { if (event.key === Qt.Key_Up) { myListView.moveContent(true) event.accepted = true } else if (event.key === Qt.Key_Down) { myListView.moveContent(false) event.accepted = true } else { event.accepted = false } } }
main.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") ListModel { id: myModel Component.onCompleted: { for (var i=0; i<50; ++i) append({"number": i, "name":"Pizza"}) } } MyListView { model: myModel color: "orange" anchors.fill: parent } }
-
wrote on 7 Jun 2017, 16:18 last edited by
It doesn't work as expected, at first is too slow, but when making the move speed around 1200 it still has inertia, not as much but still annoying. Is there any trick to always get the pixelDelta?
-
wrote on 8 Jun 2017, 09:09 last edited by johngod 6 Aug 2017, 09:17
First you should set the property interactive to false (true by default).
Then you will have to force the flickable to move (when pressing a button, or when moving the mouse wheel event, for example) by incrementing/decrementing the contentX / contentY properties.
Hope it helps. -
wrote on 24 Nov 2024, 20:23 last edited by
I know it's been a few years, but this might still be helpful to someone :)
For me, this approach works:
delegate: MyDelegate { MouseArea { id: _mouseArea anchors.fill: parent } Binding { when: _mouseArea.pressed target: _listView property: "interactive" value: false } }
With this setup, you should be able to scroll the list view using the scroll wheel. When you perform a press-and-drag gesture, it will disable the scrolling or flicking behavior. Once you release the mouse button, the binding will be restored, making the list view interactive again, so you can scroll with the mouse wheel once more.
Even when you have multiple elements (i.e., instantiated delegates), dragging across them won't reset the interactive property until you release the mouse button.