この記事はいくつかのフォーラムのスレッド(下部にリンクしました)での質問と回答を受けて作成されたものです。コードや解説でのこの記事への貢献を歓迎します。
GridView でのドラッグ&ドロップ
このサンプルは iOS スタイルのドラッグ&ドロップ( 参考ビデオ [youtube.com] )を GridView と ListModel で作成したものです。
このサンプルは3つのファイルから構成されています。一つがモデル(WidgetModel.qml)で、一つがデリゲート(IconItem.qml)、最後が GridView (Main.qml)です。
WidgetModel.qml
- import QtQuick 1.0
- ListModel {
- ListElement { icon: "Images/widget1.png"; gridId: 0}
- ListElement { icon: "Images/widget2.png"; gridId: 1}
- ListElement { icon: "Images/widget3.png"; gridId: 2}
- ListElement { icon: "Images/widget4.png"; gridId: 3}
- ListElement { icon: "Images/widget5.png"; gridId: 4}
- ListElement { icon: "Images/widget6.png"; gridId: 5}
- ListElement { icon: "Images/widget7.png"; gridId: 6}
- ListElement { icon: "Images/widget8.png"; gridId: 7}
- ListElement { icon: "Images/widget9.png"; gridId: 8}
- }
IconItem.qml
- import QtQuick 1.0
- Component {
- Item {
- id: main
- width: grid.cellWidth; height: grid.cellHeight
- Image {
- id: item; parent: loc
- x: main.x + 5; y: main.y + 5
- width: main.width - 10; height: main.height - 10;
- fillMode: Image.PreserveAspectFit; smooth: true
- source: icon
- Rectangle {
- anchors.fill: parent;
- border.color: "#326487"; border.width: 6
- color: "transparent"; radius: 5
- visible: item.state == "active"
- }
- Behavior on x { enabled: item.state != "active"; NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
- Behavior on y { enabled: item.state != "active"; NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
- SequentialAnimation on rotation {
- NumberAnimation { to: 2; duration: 60 }
- NumberAnimation { to: -2; duration: 120 }
- NumberAnimation { to: 0; duration: 60 }
- running: loc.currentId != -1 && item.state != "active"
- loops: Animation.Infinite; alwaysRunToEnd: true
- }
- states: State {
- name: "active"; when: loc.currentId == gridId
- PropertyChanges { target: item; x: loc.mouseX - width/2; y: loc.mouseY - height/2; scale: 0.5 }
- }
- transitions: Transition { NumberAnimation { property: "scale"; duration: 200} }
- }
- }
- }
Main.qml
- import QtQuick 1.0
- Rectangle {
- width: 640; height: 480
- color: "#222222"
- GridView {
- id: grid
- interactive: false
- anchors {
- topMargin: 60; bottomMargin: 60
- leftMargin: 140; rightMargin: 140
- fill: parent
- }
- cellWidth: 120; cellHeight: 120;
- model: WidgetModel { id: icons }
- delegate: IconItem { }
- MouseArea {
- property int currentId: -1 // Original position in model
- property int newIndex // Current Position in model
- property int index: grid.indexAt(mouseX, mouseY) // Item underneath cursor
- id: loc
- anchors.fill: parent
- onPressAndHold: currentId = icons.get(newIndex = index).gridId
- onReleased: currentId = -1
- onMousePositionChanged:
- if (loc.currentId != -1 && index != -1 && index != newIndex)
- icons.move(newIndex, newIndex = index, 1)
- }
- }
- }
ビデオ
関連するフォーラムのスレッド:
iOS Style Rearrange of Icons [developer.qt.nokia.com]
QML and Drag and Drop [developer.qt.nokia.com]

