ListView is (very) slow to move to current item
Page |
1 |
Hi,
(I don’t know why my previous post does not appears, sorry it appear twice).
I’m using a listview to display a list of 600 element, it appear that when I select alternatively first and last element, the listview take a long (long) time to scroll (animation) from first to last element (around 5s on my 2.5Ghz windows vista, Core2duo CPU).
This slow speed seems to be linked to
1) the usage of a javascript array as model
2) a ‘complex’ listview delegate to display element (not so complex in my point of view, but maybe a qml limitation ?)
Debugging by adding trace on listview’s delegate text, I can see that listview visit/create all element between first and last when it scrolls. As my element have same height, is there a way to declare that to listview in order to accelerate it ?
Thanks for your help and suggestions,
Arnaud.
PS: test source code (use a 6s timer to select first/last/first/last/… element of list view)
- import Qt 4.7
- import "TestListViewSlow2.js" as JS
- Rectangle {
- id: id0
- width : 400
- height : 600
- ListView {
- id : idLV
- clip: true
- width : id0.width
- height : id0.height
- focus: true
- model: 0 // see onCompleted
- highlightFollowsCurrentItem: true
- highlightMoveDuration: 300
- highlight: Rectangle {
- border.color : "black"
- radius: 4
- width: idLV.width
- gradient : Gradient {
- GradientStop { position: 0.0; color: "lightsteelblue" }
- GradientStop { position: 0.5; color: "white" }
- GradientStop { position: 1.0; color: "lightsteelblue" }
- }
- }
- Component {
- id: itemDelegate
- Item {
- width: idLV.width;
- height: tx1.height+10
- id : item
- Text { id: tx1; x:10; y: 6; text: idLV.model[index].name
- width : parent.width -10-10 -rect.width -(idIMG.visible ? (idIMG.width+3) : 0)-(idIMG2.visible ? (idIMG2.width+6) : 0)
- font.pixelSize:12; elide:Text.ElideMiddle
- // onTextChanged: {
- // console.log(" completed item index="+index)
- // }
- }
- Rectangle { //tag element having is_also_authors flag
- id:idIMG
- visible: idLV.model[index].is_also_author ? idLV.model[index].is_also_author : false
- color : "green"
- x: tx1.x+tx1.width+3
- width: 16 ; height: 16; radius: 8
- anchors.verticalCenter : parent.verticalCenter
- }
- Rectangle { //tag elemnt having is_illustrator
- id:idIMG2
- visible: idLV.model[index].is_illustrator ? idLV.model[index].is_illustrator : false
- //source: "images/camera.png"
- color: "darkMagenta"
- width: 16; height: 16; radius:8
- x: idIMG.visible ? (idIMG.x+idIMG.width+3) : tx1.x+tx1.width+3
- anchors.verticalCenter : parent.verticalCenter
- }
- Rectangle {
- id: rect
- color : idLV.model[index].valid ? "midnightBlue" : "darkRed"
- radius: height/2
- smooth:true
- width : tx2.width+tx2.height+4
- height: tx2.height+4
- y : 5
- x : item.width-8-width
- Text { id: tx2; text: idLV.model[index].count; font.pixelSize : 10; color:"white"
- anchors.verticalCenter:rect.verticalCenter; anchors.horizontalCenter: rect.horizontalCenter }
- }
- MouseArea {
- anchors.fill : parent
- onClicked: {
- idLV.currentIndex = index
- }
- }
- }
- }
- delegate: itemDelegate
- Component.onCompleted: {
- idLV.model = JS.getModel()
- }
- }
- Timer {
- id: idTimer
- repeat: true
- interval: 6000
- triggeredOnStart: true
- onTriggered: {
- //force full scroll of list view
- var nci = idLV.currentIndex==0 ? 580 : 0
- console.log("Timer set idLV.currentIndex = "+nci)
- idLV.currentIndex = nci
- }
- running: true
- }
- }
The associated .js file:
- .pragma library
- var model_cache
- function getModel() {
- if( !model_cache ) {
- model_cache = __createModel()
- }
- return model_cache
- }
- function __createModel() {
- var ary = []
- for( var i=0; i<600; i++ ) {
- var e = { name: "Entry #"+i, count: 1, valid: true }
- e.count = i
- if( i==0 ) e.valid=false
- if( i%8==0 ) {
- e.is_illustrator = true
- if( i==0 ) {
- e.is_also_author = true
- }
- }
- ary.push( e )
- }
- return ary
- }
19 replies
It’s impossible.
http://developer.qt.nokia.com/forums/viewthread/1368 [developer.qt.nokia.com]
Write my own listview it’s possibility, but a total waste of time.
enhance behior/ability of existing listview may be more useful for more people. (I guess)
In my point of view, if listview visits all element in order to get their height,
it must exist a property of listview saying ‘all elements have same height’.
With that property listview may discover once the height and remember it in order to accelerate the scroll.
(thanks for pointing me thread 1368, it’s the same issue).
ListView will move the highlight from its current position to the new current item, scrolling the view as it moves. If your model is slow to provide data or you have a complex delegate then it will struggle to scroll smoothly. The best solution is to move the view directly to the target index and then set the currentIndex, e.g.
- idLV.positionViewAtIndex(nci, ListView.Visible)
- idLV.currentIndex = nci
Andre, where is it in QListView? QListView also evaluates height for all elements.
It is right here [doc.qt.nokia.com]. You can tell QListView that the items are all the same size, and then it only evaluates the hight of the first item.
You must log in to post a reply. Not a member yet? Register here!



