Search code examples
qtgridqmlqt-quick

QML: How to move items within a grid


I have a 4x4 grid and I want to associate arrow key presses with the movement of items within the grid. How does one do that?

Here is a sample QML:

import QtQuick 1.1

Rectangle {
    id: main;
    width: 500; height: 500;
    color: "darkgreen";

    property int emptyBlock: 16;

    Grid {
        id: grid16;
        x: 5; y: 5;
        width: 490; height: 490;
        rows: 4; columns: 4; spacing: 5;

        Repeater {
            model: 1;
            Rectangle {
                width: 118; height: 118; color: "darkblue";
            }
        }
    }

    Keys.onRightPressed: pressRight();

    function pressRight() {
        console.log("Left key pressed");
    }

    focus: true;
}

Update 1: Thanks to sebasgo and alexisdm for the answers. If moving within a grid is not that easy why we have the move transition property [http://qt-project.org/doc/qt-4.8/qml-grid.html#move-prop]


Solution

  • You'd better use a GridView Item instead of your Grid approach.

    This way you can use it's currentIndex property to choose which item to move like this:

    import QtQuick 1.1
    
    Rectangle {
        id: main;
        width: 500; height: 500;
        color: "darkgreen";
    
        property int emptyBlock: 16;
    
        GridView {
            id: grid16;
            x: 5; y: 5;
            width: 490; height: 490;
    
            model: gridModel
    
            delegate: Component{
              Rectangle {
                width: 118; height: 118; color: "darkblue";
                Text {
                  anchors.centerIn: parent
                  font.pixelSize: 20
                  text: value
                }
              }
            }
        }
    
        ListModel {
          id: gridModel
          ListElement {value: 1}
          ListElement {value: 2}
          ListElement {value: 3}
          ListElement {value: 4}
        }
    
        Keys.onRightPressed: {
          gridModel.move(grid16.currentIndex, grid16.currentIndex+1, 1)
        }
    
        Keys.onLeftPressed: {
          gridModel.move(grid16.currentIndex, grid16.currentIndex-1, 1)
        }
    
        focus: true;
    }