[Development] ListView.positionViewAtIndex() seems to be unreliable during object initialization

Michael Zanetti michael.zanetti at canonical.com
Mon Jun 2 18:36:05 CEST 2014


Hi,

I think this is related to a similar issue I've been running into. We 
identified it to be related to the snapping of the ListView which makes it snap 
to somewhere else then one would expect for the initial positioning.

In your example there seems to be an issue that you set snapMode to 
ListView.SnapPosition which doesn't seem to be a valid value for that (its 
defined for positionViewAtIndex only) so I'm not sure which snap mode is 
enabled in your case. In any case, you might want to dig into that direction.

We came up with a patch that would get around it. However, due to some other 
ramifications that patch never landed.

Here's the according bug report and patch:

https://bugreports.qt-project.org/browse/QTBUG-32251
https://codereview.qt-project.org/#change,60535

The related code can be found here:

http://bazaar.launchpad.net/~unity-team/unity8/trunk/view/head:/qml/Launcher/LauncherPanel.qml

Hope this helps,
Michael


On Saturday 31 May 2014 23:19:44 Baldo Davide wrote:
> Hello,
> 
> I'm having in issue with ListView.positionViewAtIndex(), i'm changing the
> index with the last selection of the user in Component.onCompleted(),
> but positionViewAtIndex() seems to behave randomly: sometime the listview
> is moved correctly, sometime is off by 1 or 2 items.
> I've been having this issue since 5.0 and i can still reproduce it on 5.3,
> i spent several hours trying to debug it but without luck, in the end i
> added a workaround:
> 
> Timer {
> 
>     interval: 100
> 
>     repeat: false
> 
>     running: true
> 
>     onTriggered: {
> 
>       main.alignIndex()
> 
>     }
> 
>  }.
> but it's really a bad solution, and it's even visible.
> 
> Is it wrong to call positionViewAtIndex() inside Component.onCompleted()?
> If so, when should i call it?
> 
> The component is a simple digit selector.
> 
> --- CODE ---
> 
> import QtQuick 2.0
> 
> 
> Rectangle {
> 
>   id: main
> 
>   width: 60
> 
>   height: 180
> 
>   color: "transparent"
> 
>   border.color: "black"
> 
>   border.width: 3
> 
>   radius: 3
> 
>   clip: true
> 
> 
>   property int initialDigit: 0;
> 
>   property int digit: 0;
> 
>   property string textColor: "violet";
> 
> 
>   function alignIndex()
> 
>   {
> 
>     var newIndex = main.digit + 50
> 
>     listView.positionViewAtIndex(newIndex,ListView.Center);
> 
>   }
> 
> 
>   /** workaround, force refresh after initialization **/
> 
>   Timer {
> 
>     interval: 100
> 
>     repeat: false
> 
>     running: true
> 
>     onTriggered: {
> 
>       main.alignIndex()
> 
>     }
> 
>   }
> 
> 
>   onDigitChanged: {
> 
>     if( main.digit >= 10 ) {
> 
>       main.digit = main.digit % 10
> 
>     }
> 
>     main.alignIndex()
> 
>   }
> 
> 
>   Component.onCompleted: {
> 
>     for( var i = 0; i < 10; i +=1 )
> 
>     {
> 
>       for( var n = 0; n < 10; n += 1 )
> 
>       {
> 
>         listModel.append({
> 
>           digit: n
> 
>         })
> 
>       }
> 
>     }
> 
> 
>     //console.log("initial digit: "+initialDigit)
> 
>     digit = initialDigit
> 
>     alignIndex();
> 
>   }
> 
> 
>   Timer {
> 
>     running: true
> 
>     repeat: false
> 
>     interval: 1
> 
>     onTriggered: {
> 
>       main.alignIndex()
> 
>     }
> 
>   }
> 
> 
>   ListView {
> 
>     id: listView
> 
>     anchors.fill: parent
> 
> 
>     snapMode: ListView.SnapPosition
> 
> 
>     Rectangle {
> 
>       anchors.left: listView.left
> 
>       anchors.right: listView.right
> 
>       anchors.margins: 3
> 
>       height: 60 * 0.8
> 
>       y: main.height/2.0 - height/2.0 - 3
> 
>       color: "#37ffffff"
> 
>     }
> 
> 
>     onMovementEnded: {
> 
>       main.digit = listView.indexAt(
> 
>         listView.contentX,
> 
>         listView.contentY + main.height/2.0
> 
>       ) % 10
> 
>     }
> 
> 
>     model: ListModel {
> 
>       id: listModel
> 
>     }
> 
> 
>     orientation: ListView.Vertical
> 
> 
>     delegate: Component
> 
>     {
> 
>       id: digitDelegate;
> 
>       Item
> 
>       {
> 
>         height: 60
> 
>         width: main.width
> 
>         Text {
> 
>           id: digitText
> 
>           anchors.fill: parent
> 
>           text: digit
> 
>           font.pixelSize: parent.height * 0.8
> 
>           verticalAlignment: Text.Center
> 
>           horizontalAlignment: Text.Center
> 
> 
>           Component.onCompleted: {
> 
>             digitText.color = main.textColor
> 
>           }
> 
>         }
> 
>       }
> 
>     }
> 
>   }
> 
> }




More information about the Development mailing list