English | 日本語 | Български

この記事はいくつかのフォーラムのスレッド(下部にリンクしました)での質問と回答を受けて作成されたものです。コードや解説でのこの記事への貢献を歓迎します。

GridView でのドラッグ&ドロップ

このサンプルは iOS スタイルのドラッグ&ドロップ( 参考ビデオ [youtube.com] )を GridView と ListModel で作成したものです。

このサンプルは3つのファイルから構成されています。一つがモデル(WidgetModel.qml)で、一つがデリゲート(IconItem.qml)、最後が GridView (Main.qml)です。

WidgetModel.qml

  1. import QtQuick 1.0
  2.  
  3. ListModel {
  4.     ListElement { icon: "Images/widget1.png"; gridId: 0}
  5.     ListElement { icon: "Images/widget2.png"; gridId: 1}
  6.     ListElement { icon: "Images/widget3.png"; gridId: 2}
  7.     ListElement { icon: "Images/widget4.png"; gridId: 3}
  8.     ListElement { icon: "Images/widget5.png"; gridId: 4}
  9.     ListElement { icon: "Images/widget6.png"; gridId: 5}
  10.     ListElement { icon: "Images/widget7.png"; gridId: 6}
  11.     ListElement { icon: "Images/widget8.png"; gridId: 7}
  12.     ListElement { icon: "Images/widget9.png"; gridId: 8}
  13. }

IconItem.qml

  1. import QtQuick 1.0
  2.  
  3. Component {
  4.     Item {
  5.         id: main
  6.         width: grid.cellWidth; height: grid.cellHeight
  7.         Image {
  8.             id: item; parent: loc
  9.             x: main.x + 5; y: main.y + 5
  10.             width: main.width - 10; height: main.height - 10;
  11.             fillMode: Image.PreserveAspectFit; smooth: true
  12.             source: icon
  13.             Rectangle {
  14.                 anchors.fill: parent;
  15.                 border.color: "#326487"; border.width: 6
  16.                 color: "transparent"; radius: 5
  17.                 visible: item.state == "active"
  18.             }
  19.             Behavior on x { enabled: item.state != "active"; NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
  20.             Behavior on y { enabled: item.state != "active"; NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
  21.             SequentialAnimation on rotation {
  22.                 NumberAnimation { to:  2; duration: 60 }
  23.                 NumberAnimation { to: -2; duration: 120 }
  24.                 NumberAnimation { to:  0; duration: 60 }
  25.                 running: loc.currentId != -1 && item.state != "active"
  26.                 loops: Animation.Infinite; alwaysRunToEnd: true
  27.             }
  28.             states: State {
  29.                 name: "active"; when: loc.currentId == gridId
  30.                 PropertyChanges { target: item; x: loc.mouseX - width/2; y: loc.mouseY - height/2; scale: 0.5 }
  31.             }
  32.             transitions: Transition { NumberAnimation { property: "scale"; duration: 200} }
  33.         }
  34.     }
  35. }

Main.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     width: 640;  height: 480
  5.     color: "#222222"
  6.     GridView {
  7.         id: grid
  8.         interactive: false
  9.         anchors {
  10.             topMargin: 60; bottomMargin: 60
  11.             leftMargin: 140; rightMargin: 140
  12.             fill: parent
  13.         }
  14.         cellWidth: 120; cellHeight: 120;
  15.         model: WidgetModel { id: icons }
  16.         delegate: IconItem { }
  17.         MouseArea {
  18.             property int currentId: -1                       // Original position in model
  19.             property int newIndex                            // Current Position in model
  20.             property int index: grid.indexAt(mouseX, mouseY) // Item underneath cursor
  21.             id: loc
  22.             anchors.fill: parent
  23.             onPressAndHold: currentId = icons.get(newIndex = index).gridId
  24.             onReleased: currentId = -1
  25.             onMousePositionChanged:
  26.                 if (loc.currentId != -1 && index != -1 && index != newIndex)
  27.                     icons.move(newIndex, newIndex = index, 1)
  28.         }
  29.     }
  30. }

ビデオ

関連するフォーラムのスレッド:
iOS Style Rearrange of Icons [developer.qt.nokia.com]
QML and Drag and Drop [developer.qt.nokia.com]

Categories:

  • Japanese
  • snippets
  •