Qt QML:如何在网格中移动项目
我有一个4x4网格,我想将箭头键按下与网格内项目的移动相关联。你是怎么做到的 以下是一个示例QML:Qt QML:如何在网格中移动项目,qt,grid,qml,qt-quick,Qt,Grid,Qml,Qt Quick,我有一个4x4网格,我想将箭头键按下与网格内项目的移动相关联。你是怎么做到的 以下是一个示例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:
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;
}
更新1:感谢sebasgo和Alexism的回答。如果在网格中移动不是那么容易,那么为什么我们有
move
transition属性[http://qt-project.org/doc/qt-4.8/qml-grid.html#move-prop]栅格无法直接操纵所包含项目的位置。相反,它们的位置直接来自网格子项的物理顺序。QML中需要动态操作子项,因此我认为您应该放弃网格
项,并使用x
和y
属性显式指定子项的位置。应用于您的代码时,可能会出现以下情况:
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;
}
更新1:
网格(与中继器结合)可用于可视化模型,例如XmlListModel
项或qabstractemmodel
子项
使用move
属性,可以轻松地以动画方式对模型中的布局更改做出反应(如果删除/添加了条目)。尽管如此,表格中的项目仍然严格按照模型条目的顺序排列
因此,如果您想要手动控制项目的位置,即使在蜂窝布局中,也不建议使用网格。您可以在要移动的项目之前更改项目的数量以更改其位置:
import QtQuick 1.1
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
property int emptyBlock: 16;
property int posX: 0;
property int posY: 0;
Grid {
id: grid;
x: 5; y: 5;
width: 490; height: 490;
rows: 4; columns: 4; spacing: 5;
Repeater {
id: beforeTheItem
model: main.posX + parent.columns * main.posY
Rectangle {
width: 118; height: 118; color: "transparent";
}
}
Rectangle {
id:theItem
width: 118; height: 118; color: "darkblue";
}
}
Keys.onPressed: {
// To avoid flickering, the item is hidden before the change
// and made visible again after
theItem.visible = false;
switch(event.key) {
case Qt.Key_Left: if(posX > 0) posX--;
break;
case Qt.Key_Right: if(posX < grid.columns - 1) posX++;
break;
case Qt.Key_Up: if(posY > 0) posY--;
break;
case Qt.Key_Down: if(posY < grid.rows - 1) posY++;
break;
}
theItem.visible = true;
}
focus: true;
}
导入QtQuick 1.1
长方形{
id:main;
宽度:500;高度:500;
颜色:“暗绿色”;
属性int emptyBlock:16;
属性int posX:0;
属性int posY:0;
网格{
id:网格;
x:5;y:5;
宽度:490;高度:490;
行:4;列:4;间距:5;
中继器{
身份证号码:beforeitem
型号:main.posX+parent.columns*main.posY
长方形{
宽度:118;高度:118;颜色:“透明”;
}
}
长方形{
id:Iteem
宽度:118;高度:118;颜色:“深蓝色”;
}
}
按键。ON按下:{
//为避免闪烁,在更改之前将隐藏该项
//之后又出现了
可见=假;
开关(事件键){
案例Qt.Key_左:如果(posX>0)posX--;
打破
case Qt.Key_Right:if(posX0)posY--;
打破
case Qt.Key_Down:if(posY
您最好使用网格视图
项,而不是网格
方法
通过这种方式,您可以使用它的currentIndex
属性选择要移动的项目,如下所示:
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;
}
现在,通过使用或以上选项,您可以轻松移动物品:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
Window
{
visible: true
MainForm
{
GridLayout {
id: gridLayout
columns: 3
property int oneRow: 0
property int oneCol: 0
Text { id: one; Layout.row :grid.oneRow; Layout.column: grid.oneCol; text: "My"; font.bold: true; }
Text { text: "name"; color: "red" }
Text { text: "is"; font.underline: true }
Text { text: "not"; font.pixelSize: 20 }
Text { text: "Ravan"; font.strikeout: true }
}
Component.onCompleted:
{
gridLayout.oneRow = 1
gridLayout.oneCol = 2
}
}
}
GridView是一个非常令人困惑的怪物。它只填充给定模型中的一行,这会导致混淆,因为它被称为网格。但它仍然可以用作固定大小的网格,如下面的示例所示。在4x4大小的网格上,可以使用箭头键移动单个正方形
GridView {
id: grid16;
anchors.fill: parent
cellWidth: parent.width / 2
cellHeight: parent.height / 2
model: gridModel
delegate:
Rectangle {
Component.onCompleted: if( index >= 1 ) visible = false
width: grid16.cellWidth ; height: grid16.cellHeight ; color: "yellow";
Text {
anchors.centerIn: parent
font.pixelSize: 20
text: value
}
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 1000 }
}
}
ListModel {
id: gridModel
ListElement {value: 1}
//Necessary, otherwise the grid will have the dimension 1x1
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) }
Keys.onUpPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex-2, 1) }
Keys.onDownPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex+2, 1) }
focus: true;
}
要更新1,请参见下面的示例,其中可以在4x4大小的网格上移动项目。GridLayout不支持模型。如果您使用的是更大的网格,那么您肯定想要使用模型,并且需要切换到GridView。使用转发器来使用模型。在网格布局中移动项目似乎更容易