6

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: 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とalexisdmに感謝します。moveグリッド内での移動がそれほど簡単ではない場合、遷移プロパティ[http://qt-project.org/doc/qt-4.8/qml-grid.html#move-prop]があるのはなぜですか。

4

5 に答える 5

8

アプローチGridViewの代わりにアイテムを使用する方がよいでしょう。Grid

このように、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;
}
于 2012-07-31T15:36:43.613 に答える
3

グリッドを使用すると、含まれているアイテムの位置を直接操作することはできません。代わりに、それらの位置は、グリッドの子アイテムの物理的な順序から直接導き出されます。QMLで子アイテムを動的に操作する簡単な方法はないため、アイテムを破棄し、 andプロパティGridを使用して子アイテムの位置を明示的に指定する必要があると思います。コードに適用すると、次のようになります。xy

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アイテムやQAbstractItemModel子孫などのモデルを視覚化できます。

プロパティを使用moveすると、モデルのレイアウト変更(エントリが削除/追加された場合)にアニメーションで簡単に対応できます。それでも、の項目Gridはモデルのエントリの順序で厳密に配置されます。

したがって、セルラーレイアウトであっても、アイテムの位置を手動で制御したい場合は、aを使用することGridはお勧めしません。

于 2012-07-30T09:25:55.903 に答える
1

移動するアイテムの前にあるアイテムの数を変更して、その位置を変更できます。

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;
}
于 2012-07-30T22:25:15.297 に答える
1

これで、Qt 5.1以降とGridLayoutを使用することで、手間をかけずにアイテムを移動できます。

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
        }
    }
}
于 2015-06-23T07:47:01.197 に答える
1

GridViewは非常に紛らわしいモンスターです。特定のモデルから1行を入力するだけであり、GRIDと呼ばれるため、混乱を招きます。ただし、以下の例に示すように、固定サイズのグリッドとして使用することはできます。1つの正方形は、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;
}
于 2017-04-12T07:15:23.467 に答える