[SOLVED; With one qualification(see thread)] GridView Problem with *example*



  • Hi,
    So my powers of description for the problem I am having were not sufficient to inspire any solutions :-). Let me show a simple example.

    The problem: GridView Items do not come into view from off screen when changing their position in the grid.

    Example: This example illustrates how highlighting items in the grid using the arrow keys will bring off screen items into view but not when moving items. By default the grid is setup to highlight items. By pressing the "enter" key it switches modes to move the current item to the position indicated by the arrow key pressed. In the "move" mode the current item is highlighted in yellow and in the "highlight" mode it is highlighted in steel blue.

    Notice that when in "move" mode the off screen items do not come into view. You can toggle between the two modes to see what I mean by hitting the "enter" key.

    The currentIndex documentation for GridView says ...

    bq. The currentIndex property holds the index of the current item, and currentItem holds the current item. Setting the currentIndex to -1 will clear the highlight and set currentItem to null.
    If highlightFollowsCurrentItem is true, setting either of these properties will smoothly scroll the GridView so that the current item becomes visible.

    Since the highlight follows the current index by default, the index is clearly changing so the item should come into view. Any ideas?

    @
    import QtQuick 2.3
    import QtQuick.Controls 1.2

    Rectangle {
    id: mainview
    width: 700
    height: 700
    color: "black"

    ListModel {
        id: testModel
    
        ListElement {
                name: "one"
                colorName: "red"
        }
        ListElement {
                name: "two"
                colorName: "green"
        }
        ListElement {
                name: "three"
                colorName: "blue"
        }
        ListElement {
                name: "four"
                colorName: "orange"
        }
        ListElement {
                name: "five"
                colorName: "cyan"
        }
        ListElement {
                name: "six"
                colorName: "white"
        }
        ListElement {
                name: "seven"
                colorName: "grey"
        }
        ListElement {
                name: "eight"
                colorName: "magenta"
        }
        ListElement {
                name: "nine"
                colorName: "darkred"
        }
        ListElement {
                name: "seven"
                colorName: "darkgreen"
        }
        ListElement {
                name: "eight"
                colorName: "darkblue"
        }
        ListElement {
                name: "nine"
                colorName: "darkmagenta"
        }
    
    }
    
    
    Component {
        id: highlightBar
    
        Rectangle {
            id: highlightRect
    
            color: "lightSteelBlue"
            width: view.cellWidth; height: view.cellHeight
        }
    }
    
    
    GridView {
        id: view
        height: parent.height
        width: 225*3
        cellWidth: 225; cellHeight: 225
        anchors.horizontalCenter: parent.horizontalCenter
        model: testModel
        highlight: highlightBar
        highlightMoveDuration: 200
        property string mode : "highlight"
        focus: true
    
        delegate: Rectangle{
                        width: view.cellWidth
                        height: view.cellHeight
                        color: "transparent"
    
                        Rectangle {
                            anchors.centerIn: parent
                            width: 200
                            height: 200
                            color: colorName
                        }
                  }
    
        move: Transition {
                 NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
            }
    
        displaced: Transition {
                 NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
            }
    
    
        Keys.onRightPressed:  {
            if (mode == "move") {
                testModel.move(view.currentIndex,view.currentIndex+1,1);
            }else{
                view.moveCurrentIndexRight();
            }
        }
    
        Keys.onLeftPressed:  {
            if (mode == "move") {
                testModel.move(view.currentIndex,view.currentIndex-1,1);
            }else{
                view.moveCurrentIndexLeft();
            }
        }
    
        Keys.onUpPressed:  {
            if (mode == "move") {
                model.move(view.currentIndex,view.currentIndex - 3,1);
            }else{
                view.moveCurrentIndexUp();
    
            }
        }
    
        Keys.onDownPressed:  {
            if (mode == "move") {
                model.move(view.currentIndex,view.currentIndex + 3,1);
            }else{
                view.moveCurrentIndexDown();
            }
        }
    
    
        Keys.onReturnPressed: {
            if (mode == "move") {
                highlightItem.color = "lightSteelBlue";
                highlightItem.opacity = .4;
                view.highlightMoveDuration = 200;
                mode = "highlight";
            }else{
                highlightItem.color = "yellow";
                highlightItem.opacity = 1.0;
                view.highlightMoveDuration = 0;
                mode = "move";
            }
    
        }
    
    }
    

    }

    @


  • Moderators

    Hi,

    It seems move doesn't set the currentIndex. You can set the currentIndex manually and then use "positionViewAtIndex":http://qt-project.org/doc/qt-5/qml-qtquick-gridview.html#positionViewAtIndex-method to make the item visible properly.
    For eg. I modified your example,
    @
    Keys.onUpPressed: {
    if (mode == "move") {
    model.move(view.currentIndex,view.currentIndex - 3,1);
    currentIndex = currentIndex - 3
    positionViewAtIndex(currentIndex,GridView.Contain)
    }else{
    view.moveCurrentIndexUp();
    }
    }

    Keys.onDownPressed: {
    if (mode == "move") {
    model.move(currentIndex,currentIndex + 3,1);
    currentIndex = currentIndex + 3
    positionViewAtIndex(currentIndex,GridView.Contain)
    }else{
    view.moveCurrentIndexDown();
    }
    }
    @



  • Hey thanks, that did the trick. :-)



  • FYI ... This worked fine until I tried to scale it up to around twenty items in the grid. Then when I tried hitting the left key repeatedly to move an item from the bottom of the grid to the top I ran into a problem where the screen would periodically go completely black for no reason.

    Turns out I needed to set the GridView's cacheBuffer property to an appropriately high number so that enough delegates were retained outside the visible area of the view. After I did that it worked fine.

    Thanks again


  • Moderators

    That's Good. Thanks for the Info. Added to my Lib. :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.