Drag and Drop within a GridView: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(Fix code blocks formating)
 
(14 intermediate revisions by 8 users not shown)
Line 1: Line 1:
[[Category:snippets]]<br />[[Category:Developing_with_Qt::Qt Quick]]<br />[[Category:Developing_with_Qt::Qt Quick::QML]]<br />[[Category:Developing_with_Qt::Qt Quick::Tutorial]]<br />'''English''' | [[Drag_and_Drop_within_a_GridView_Japanese|日本語]] | [[Drag_and_Drop_within_a_GridView_Bulgarian|Български]]
{{LangSwitch}}


This wiki entry is created in response to a few forum threads (links at bottom) asking for this method. Feel free to contribute to this article with explanations or code.
[[Category:Snippets::QML]]
[[Category:Developing_with_Qt::Qt Quick::QML]]
[[Category:Developing_with_Qt::Qt Quick::Tutorial]]
 
This wiki entry is created in response to a few forum threads (links at bottom) asking for this method.
Feel free to contribute to this article with explanations or code.


= Drag and Drop within a GridView =
= Drag and Drop within a GridView =


This example will demonstrate the iOS style (&quot;video here&amp;quot;:http://www.youtube.com/watch?v=qnXoGnUU6uI ) of dragging and dropping ListModel elements within a GridView.
This example will demonstrate the iOS style ([http://www.youtube.com/watch?v=qnXoGnUU6uI video here] ) of dragging and dropping ListModel elements within a GridView.


There are three files in this example. One for the model (WidgetModel.qml), one for the delegate (IconItem.qml) and one for the GridView (Main.qml).
There are three files in this example. One for the model (WidgetModel.qml), one for the delegate (IconItem.qml) and one for the GridView (Main.qml).


'''WidgetModel.qml'''<br /><code>import QtQuick 1.0
'''WidgetModel.qml'''
<syntaxhighlight lang="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}
}
</syntaxhighlight>
 
'''IconItem.qml'''
<syntaxhighlight lang="qml">
import QtQuick 2.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; z: 10 }
        }
 
        transitions: Transition { NumberAnimation { property: "scale"; duration: 200} }
        } //Image
    } //Item
} //Component
</syntaxhighlight>
 
'''Main.qml'''
<syntaxhighlight lang="qml">
import QtQuick 2.0
import QtQuick.Controls 2.2
 
ApplicationWindow {
    width: 640; height: 480
    color: "#222222"
    visible: true
 
    GridView {
        id: grid
        interactive: false
        anchors.fill: parent
        topMargin: 60
        bottomMargin: 60
        leftMargin: 140
        rightMargin: 140


ListModel {<br /> ListElement { icon: &quot;Images/widget1.png&amp;quot;; gridId: 0}<br /> ListElement { icon: &quot;Images/widget2.png&amp;quot;; gridId: 1}<br /> ListElement { icon: &quot;Images/widget3.png&amp;quot;; gridId: 2}<br /> ListElement { icon: &quot;Images/widget4.png&amp;quot;; gridId: 3}<br /> ListElement { icon: &quot;Images/widget5.png&amp;quot;; gridId: 4}<br /> ListElement { icon: &quot;Images/widget6.png&amp;quot;; gridId: 5}<br /> ListElement { icon: &quot;Images/widget7.png&amp;quot;; gridId: 6}<br /> ListElement { icon: &quot;Images/widget8.png&amp;quot;; gridId: 7}<br /> ListElement { icon: &quot;Images/widget9.png&amp;quot;; gridId: 8}<br />}</code>
        cellWidth: 120
        cellHeight: 120
        model: WidgetModel { id: icons }
        delegate: IconItem { }
    }


'''IconItem.qml'''<br /><code>import QtQuick 1.0
    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


Component {<br /> Item {<br /> id: main<br /> width: grid.cellWidth; height: grid.cellHeight<br /> Image {<br /> id: item; parent: loc<br /> x: main.x + 5; y: main.y + 5<br /> width: main.width - 10; height: main.height - 10;<br /> fillMode: Image.PreserveAspectFit; smooth: true<br /> source: icon<br /> Rectangle {<br /> anchors.fill: parent;<br /> border.color: &quot;#326487&amp;quot;; border.width: 6<br /> color: &quot;transparent&amp;quot;; radius: 5<br /> visible: item.state  &amp;quot;active&amp;quot;
        id: loc
            &amp;#125;
        anchors.fill: parent
            Behavior on x &amp;#123; enabled: item.state != &amp;quot;active&amp;quot;; NumberAnimation &amp;#123; duration: 400; easing.type: Easing.OutBack &amp;#125; &amp;#125;
        onPressAndHold: currentId = icons.get(newIndex = index).gridId
            Behavior on y &amp;#123; enabled: item.state != &amp;quot;active&amp;quot;; NumberAnimation &amp;#123; duration: 400; easing.type: Easing.OutBack &amp;#125; &amp;#125;
        onReleased: currentId = -1
            SequentialAnimation on rotation &amp;#123;
        onPositionChanged: {
                NumberAnimation &amp;#123; to:  2; duration: 60 &amp;#125;
            if (loc !== currentId && index !== -1 && index !== newIndex)
                NumberAnimation &amp;#123; to: -2; duration: 120 &amp;#125;
                 icons.move(newIndex, newIndex = index, 1)
                NumberAnimation &amp;#123; to: 0; duration: 60 &amp;#125;
        }
                running: loc.currentId != -1 &amp;amp;&amp;amp; item.state != &amp;quot;active&amp;quot;
    }
                 loops: Animation.Infinite; alwaysRunToEnd: true
}
            &amp;#125;
</syntaxhighlight>
            states: State &amp;#123;
                name: &amp;quot;active&amp;quot;; when: loc.currentId  gridId<br /> PropertyChanges { target: item; x: loc.mouseX - width/2; y: loc.mouseY - height/2; scale: 0.5; z: 10 }<br /> }<br /> transitions: Transition { NumberAnimation { property: &quot;scale&amp;quot;; duration: 200} }<br /> }<br /> }<br />}</code>


'''Main.qml'''<br /><code>import QtQuick 1.0


Rectangle {<br /> width: 640; height: 480<br /> color: &quot;#222222&amp;quot;<br /> GridView {<br /> id: grid<br /> interactive: false<br /> anchors {<br /> topMargin: 60; bottomMargin: 60<br /> leftMargin: 140; rightMargin: 140<br /> fill: parent<br /> }<br /> cellWidth: 120; cellHeight: 120;<br /> model: WidgetModel { id: icons }<br /> delegate: IconItem { }<br /> MouseArea {<br /> property int currentId: –1 // Original position in model<br /> property int newIndex // Current Position in model<br /> property int index: grid.indexAt(mouseX, mouseY) // Item underneath cursor<br /> id: loc<br /> anchors.fill: parent<br /> onPressAndHold: currentId = icons.get(newIndex = index).gridId<br /> onReleased: currentId = –1<br /> onMousePositionChanged:<br /> if (loc.currentId [[Image:= -1 &amp;&amp; index |= -1 &amp;&amp; index ]]= –1 &amp;&amp; index != newIndex)<br /> icons.move(newIndex, newIndex = index, 1)<br /> }<br /> }<br />}</code>
'''[https://www.youtube.com/watch?v=4tt5hQYS4Fo Video]'''


'''Video'''<br />[YouTubeID:4tt5hQYS4Fo]


Relevant forum threads:<br />&quot;iOS Style Rearrange of Icons&amp;quot;:http://developer.qt.nokia.com/forums/viewthread/2327/
Relevant forum threads:<br>
[http://forum.qt.io/topic/2279/solved-ios-style-rearrange-of-icons iOS Style Rearrange of Icons]

Latest revision as of 21:52, 12 April 2023

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

This wiki entry is created in response to a few forum threads (links at bottom) asking for this method. Feel free to contribute to this article with explanations or code.

Drag and Drop within a GridView

This example will demonstrate the iOS style (video here ) of dragging and dropping ListModel elements within a GridView.

There are three files in this example. One for the model (WidgetModel.qml), one for the delegate (IconItem.qml) and one for the 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 2.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; z: 10 }
        }

        transitions: Transition { NumberAnimation { property: "scale"; duration: 200} }
        } //Image
    } //Item
} //Component

Main.qml

import QtQuick 2.0
import QtQuick.Controls 2.2

ApplicationWindow {
    width: 640; height: 480
    color: "#222222"
    visible: true

    GridView {
        id: grid
        interactive: false
        anchors.fill: parent
        topMargin: 60
        bottomMargin: 60
        leftMargin: 140
        rightMargin: 140

        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
        onPositionChanged: {
            if (loc !== currentId && index !== -1 && index !== newIndex)
                icons.move(newIndex, newIndex = index, 1)
        }
    }
}


Video


Relevant forum threads:
iOS Style Rearrange of Icons