Move QML ListView via buttons
-
Hello,
I would like to be able to move a list view via button, with the following behaviors:
-
Move repeatedly when I click several time on button
-
Move continuously on press and hold
-
Display the scrollbar when moving via buttons
I tried several methods:
- Use positionViewAtIndex() method
Instantaneous change without smooth moving.
- Moving the currentIndex
Not working properly if current index is not a visible item.
Delay before moving when currentIndex change the first time (around 1s) .- Use flick() method
Works for moving
Only method which allow to display the scroll bar when moving
Cannot click repeatedly on the button, the previous flick has to be finished.I still don't know how to achieve smooth moving when clicking repeatedly, neither how to move continuously on press and hold.
My current demo with flick method:
import QtQuick 2.7 import QtQuick.Controls 2.0 Rectangle { property color accentColor: "#ff00b374" id: demo width: 800 height: 600 color: "#ff303030" Rectangle { width: parent.width/2-32 height: parent.height-32 x: 16 y: 16 color: accentColor clip: true ListView { id: listView width: parent.width height: parent.height // When scroll end align to the nearest item snapMode: ListView.SnapToItem // Clip painting to his own bounding rectangle to avoid display // data outside specified size during flick clip: true model: 100 // Increase Flick speed maximumFlickVelocity: 10000 cacheBuffer:1000 ScrollBar.vertical: ScrollBar { id: verticalScrollBar active: true orientation: Qt.Vertical opacity: verticalScrollBar.pressed?1:(listView.moving?1:0) Behavior on opacity {NumberAnimation {duration: 500}} contentItem: Rectangle { implicitWidth: 4 radius:2 implicitHeight: parent.height color: accentColor } } delegate: Rectangle { id: lineRectangle height: 32 width: listView.width // Change color based on index number for better readability color: (index & 1)? "#ffefefef" : "#ffffffff" Text { id: textField height: parent.height width: parent.width color: listView.currentIndex === index? accentColor:"#ff000000" font.pixelSize: 16 horizontalAlignment : Text.AlignHCenter text: "Element " + (index+1) } } } } // Up Button to move list up Rectangle { id: upButton height: 256 width: height//parent.width radius: height/2 x: parent.width*3/4-width/2 y: parent.height*1/4-height/2 color: "#ffffffff" Text { text: "Up" anchors.centerIn: parent color: listUp.pressed? demo.accentColor: "#ff000000" font.pixelSize: 64 } MouseArea { anchors.fill: parent id: listUp onPressed: { listView.flick(0, 1000) /*var targetIndex = listView.currentIndex-20; if (targetIndex < 0) listView.currentIndex= 0; else listView.currentIndex= targetIndex*/ } } } // Down Button to move list down Rectangle { id: downButton height: upButton.height width: upButton.width radius: upButton.radius color: upButton.color x: parent.width*3/4-width/2 y: parent.height*3/4-height/2 Text { text: "Down" anchors.centerIn: parent color: listDown.pressed? demo.accentColor: "#ff000000" font.pixelSize: 64 } MouseArea { anchors.fill: parent id: listDown onClicked: { listView.flick(0, -1000); /*var targetIndex = listView.currentIndex+20; if (targetIndex >= listView.count) listView.currentIndex= listView.count-1; else listView.currentIndex= targetIndex*/ } } } }
-
-
HI,
Solution to your first point "Move repeatedly when I click several time on button". Please find below
You have to do few things
- please call accentColor everywhere using the id "demo", as what you called in other places.
- In ListView, onCompleted slot, set the listView's current index to 0. (listView.currentIndex = 0)
- In onMousePressed for UP button, use the following lines
if (listView.currentIndex < listView.count-1)
{
listView.currentIndex += 1
} - In onMousePressed for Down button, use the following lines
if (listView.currentIndex > 0)
{
listView.currentIndex -= 1
}
-
Hi,
You can also find an example of programmatically scrolling a ListView in this github sample.
It uses the AppListView component from the V-Play SDK, but the approach should work as well with a plain Qt ListView.
Cheers,
Lorenz -
Hello @AbuFahima,
I already tried this method (see my first post), it is also in comment in my example and the currentIndex is highlighted.
But I found theses issues with this method:
- Moving the currentIndex
Not working properly if current index is not a visible item.
Delay before moving when currentIndex change the first time (around 1s) . -
Something like this?
import QtQuick 2.7 import QtQuick.Window 2.2 import QtQuick.Controls 2.0 Window { id: demo width: 800 height: 600 visible: true color: "#ff303030" property color accentColor: "#ff00b374" Rectangle { width: parent.width/2-32 height: parent.height-32 x: 16 y: 16 color: accentColor clip: true ListView { id: listView width: parent.width height: parent.height // When scroll end align to the nearest item snapMode: ListView.SnapToItem // Clip painting to his own bounding rectangle to avoid display // data outside specified size during flick clip: true model: 100 // Increase Flick speed maximumFlickVelocity: 10000 cacheBuffer:1000 ScrollBar.vertical: ScrollBar { id: verticalScrollBar active: pressed || listView.moving || listUp.pressed || listDown.pressed orientation: Qt.Vertical opacity: active ? 1:0 Behavior on opacity {NumberAnimation {duration: 500}} contentItem: Rectangle { implicitWidth: 4 radius:2 implicitHeight: parent.height color: accentColor } } delegate: Rectangle { id: lineRectangle height: 32 width: listView.width // Change color based on index number for better readability color: (index & 1)? "#ffefefef" : "#ffffffff" Text { id: textField height: parent.height width: parent.width color: listView.currentIndex === index? accentColor:"#ff000000" font.pixelSize: 16 horizontalAlignment : Text.AlignHCenter text: "Element " + (index+1) } } } } // Up Button to move list up Rectangle { id: upButton height: 256 width: height//parent.width radius: height/2 x: parent.width*3/4-width/2 y: parent.height*1/4-height/2 color: "#ffffffff" Text { text: "Up" anchors.centerIn: parent color: listUp.pressed? demo.accentColor: "#ff000000" font.pixelSize: 64 } MouseArea { anchors.fill: parent id: listUp SmoothedAnimation { target: listView property: "contentY" running: listUp.pressed velocity: 1000 to: 0 } onReleased: { if (!listView.atYBeginning) listView.flick(0, 1000) } } } // Down Button to move list down Rectangle { id: downButton height: upButton.height width: upButton.width radius: upButton.radius color: upButton.color x: parent.width*3/4-width/2 y: parent.height*3/4-height/2 Text { text: "Down" anchors.centerIn: parent color: listDown.pressed? demo.accentColor: "#ff000000" font.pixelSize: 64 } MouseArea { anchors.fill: parent id: listDown SmoothedAnimation { target: listView property: "contentY" running: listDown.pressed to: listView.contentHeight - listView.height velocity: 1000 } onReleased: { if (!listView.atYEnd) listView.flick(0, -1000) } } } }