[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