December 17, 2010

arno5m arno5m
Lab Rat
6 posts

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)

  1. import Qt 4.7
  2. import "TestListViewSlow2.js" as JS
  3.  
  4. Rectangle {
  5.     id: id0
  6.     width : 400
  7.     height : 600
  8.  
  9.     ListView {
  10.         id : idLV
  11.         clip: true
  12.         width : id0.width
  13.         height : id0.height
  14.         focus: true
  15.         model: 0 // see onCompleted
  16.         highlightFollowsCurrentItem: true
  17.         highlightMoveDuration: 300
  18.         highlight: Rectangle {
  19.             border.color : "black"
  20.             radius: 4
  21.             width: idLV.width
  22.             gradient : Gradient {
  23.                 GradientStop { position: 0.0; color: "lightsteelblue" }
  24.                 GradientStop { position: 0.5; color: "white" }
  25.                 GradientStop { position: 1.0; color: "lightsteelblue" }
  26.             }
  27.         }
  28.         Component {
  29.             id: itemDelegate
  30.             Item {
  31.                 width: idLV.width;
  32.                 height: tx1.height+10
  33.                 id : item
  34.  
  35.                 Text { id: tx1; x:10; y: 6; text: idLV.model[index].name
  36.                     width : parent.width -10-10 -rect.width -(idIMG.visible ? (idIMG.width+3) : 0)-(idIMG2.visible ? (idIMG2.width+6) : 0)
  37.                     font.pixelSize:12; elide:Text.ElideMiddle
  38. //                    onTextChanged: {
  39. //                        console.log(" completed item index="+index)
  40. //                    }
  41.                 }
  42.                 Rectangle { //tag element having is_also_authors flag
  43.                     id:idIMG
  44.                     visible: idLV.model[index].is_also_author ? idLV.model[index].is_also_author : false
  45.                     color : "green"
  46.                     x: tx1.x+tx1.width+3
  47.                     width: 16 ; height: 16; radius: 8
  48.                     anchors.verticalCenter : parent.verticalCenter
  49.                 }
  50.                 Rectangle { //tag elemnt having is_illustrator
  51.                     id:idIMG2
  52.                     visible: idLV.model[index].is_illustrator ? idLV.model[index].is_illustrator : false
  53.                     //source: "images/camera.png"
  54.                     color: "darkMagenta"
  55.                     width: 16; height: 16; radius:8
  56.                     x: idIMG.visible ? (idIMG.x+idIMG.width+3) : tx1.x+tx1.width+3
  57.                     anchors.verticalCenter : parent.verticalCenter
  58.                 }
  59.                 Rectangle {
  60.                     id: rect
  61.                     color : idLV.model[index].valid ? "midnightBlue" : "darkRed"
  62.                     radius: height/2
  63.                     smooth:true
  64.                     width : tx2.width+tx2.height+4
  65.                     height: tx2.height+4
  66.                     y : 5
  67.                     x : item.width-8-width
  68.                     Text { id: tx2; text: idLV.model[index].count; font.pixelSize : 10; color:"white"
  69.                           anchors.verticalCenter:rect.verticalCenter; anchors.horizontalCenter: rect.horizontalCenter }
  70.                 }
  71.                 MouseArea {
  72.                     anchors.fill : parent
  73.                     onClicked: {
  74.                         idLV.currentIndex = index
  75.                     }
  76.                 }
  77.             }
  78.         }
  79.         delegate: itemDelegate
  80.  
  81.         Component.onCompleted: {
  82.             idLV.model = JS.getModel()
  83.         }
  84.     }
  85.     Timer {
  86.         id: idTimer
  87.         repeat: true
  88.         interval: 6000
  89.         triggeredOnStart: true
  90.         onTriggered: {
  91.             //force full scroll of list view
  92.             var nci = idLV.currentIndex==0 ? 580 : 0
  93.             console.log("Timer set idLV.currentIndex = "+nci)
  94.             idLV.currentIndex = nci
  95.         }
  96.         running: true
  97.     }
  98. }

The associated .js file:

  1. .pragma library
  2.  
  3. var model_cache
  4.  
  5. function getModel() {
  6.     if( !model_cache ) {
  7.         model_cache = __createModel()
  8.     }
  9.     return model_cache
  10. }
  11.  
  12. function __createModel() {
  13.     var ary = []
  14.     for( var i=0; i<600; i++ ) {
  15.         var e = { name: "Entry #"+i, count: 1, valid: true }
  16.         e.count = i
  17.         if( i==0 ) e.valid=false
  18.         if( i%8==0 ) {
  19.             e.is_illustrator = true
  20.             if( i==0 ) {
  21.                 e.is_also_author = true
  22.             }
  23.         }
  24.         ary.push( e )
  25.     }
  26.  
  27.     return ary
  28. }

19 replies

December 17, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

It’s impossible.
http://developer.qt.nokia.com/forums/viewthread/1368 [developer.qt.nokia.com]

December 17, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

Write own ListView

December 17, 2010

arno5m arno5m
Lab Rat
6 posts

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).

December 17, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

arno5m, I agree with you. Sometimes it’s necessary feature.

December 20, 2010

MartinJ MartinJ
Lab Rat
14 posts

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.

  1.             idLV.positionViewAtIndex(nci, ListView.Visible)
  2.             idLV.currentIndex = nci

December 20, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

MartinJ, positionViewAtIndex also will evaluate height for all elements from current to nci.

December 20, 2010

arno5m arno5m
Lab Rat
6 posts

I’m agree with Alexander, the height of intermediary item is evaluated in this situation also. I think the solution it’s a particular API (at least one method) to set the height of item in a listview.

December 20, 2010

Andre Andre
Area 51 Engineer
6031 posts

I find it a bit weird that we run into this issue again. It in the widgets world, the need for this feature for optimization purposes was already known. QListView has it, for instance. QML should not be about reinventing the wheel, should it?

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

December 20, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

Andre, where is it in QListView? QListView also evaluates height for all elements.

December 20, 2010

Andre Andre
Area 51 Engineer
6031 posts

Alexander Kuchumov wrote:
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.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

December 20, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

Andre, I’ve missed this function:)

December 20, 2010

Andre Andre
Area 51 Engineer
6031 posts

Don’t :-) It can make a huge difference in QListViews performance.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

December 21, 2010

MartinJ MartinJ
Lab Rat
14 posts

positionViewAtIndex() does not calculate the height of intermediary items. That is the point of that function.

December 21, 2010

Alexander Kuchumov Alexander Kuchumov
Lab Rat
377 posts

MartinJ is right, positionViewAtIndex uses averageSize .

December 21, 2010

Andre Andre
Area 51 Engineer
6031 posts

How is averageSize calculated? It is not a property of the ListView element, so where does it come from?

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

Page  
1

  ‹‹ [solved] Can I fake a Keys.pressed signal?      abstract type with qmlRegisterType ››

You must log in to post a reply. Not a member yet? Register here!