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]
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;
}
Grids give you no way to manipulate the position of the contained items directly. Instead their position is directly derived from the physically order of the child items of the grid. There is no easy way to to manipulate child items in QML dynamically, so I think you should abandon the Grid
item and specify the position of the child items explicitly with the x
and y
properties. Applied to your code this could look like:
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
Item {
x: 5; y: 5;
width: 490; height: 490;
Repeater {
id: pieces
model: 1;
Rectangle {
property int column: 0
property int row: 0
x: column * 123
y: row * 123
width: 118; height: 118; color: "darkblue";
}
}
}
Keys.onRightPressed: pressRight();
function pressRight() {
console.log("Left key pressed");
pieces.itemAt(0).column++
}
focus: true;
}
Update 1:
Grids (in combination with a Repeater) can be used to visualize models, e.g., a XmlListModel
item or an QAbstractItemModel
descendent.
With move
property it's easy to react to layout changes in the model (if an entry is removed/added) in an animated way. Still, the items in the Grid
are laid out strictly in the order of the entries of the model.
So if you want have manual control over the position of your items, even in cellular layout, use of a Grid
is not advisable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With