Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
dynamicview-tutorial.qdoc
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5\page qml-dynamicview-tutorial.html tutorial
6\title QML Dynamic View Ordering Tutorial
7\brief A tutorial describing how to re-arrange items in a QML ListView
8\nextpage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
9
10This tutorial shows how items in a ListView can be re-ordered without modifying the source model.
11It demonstrates using drag and drop to reposition individual items within a view and using model
12data to dynamically sort all items in a view.
13
14Tutorial chapters:
15
16\list 1
17\li \l {QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate}{A Simple ListView and Delegate}
18\li \l {QML Dynamic View Ordering Tutorial 2 - Dragging View Items}{Dragging View Items}
19\li \l {QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items}{Moving Dragged Items}
20\li \l {QML Dynamic View Ordering Tutorial 4 - Sorting Items}{Sorting Items}
21\endlist
22
23All the code in this tutorial can be found in Qt's \c examples/quick/tutorials/dynamicview
24directory.
25*/
26
27/*!
28\title QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
29\previouspage QML Dynamic View Ordering Tutorial
30\nextpage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
31
32\example tutorials/dynamicview/dynamicview1
33\examplecategory {User Interface Components}
34
35We begin our application by defining a ListView, a model which will provide data to the view, and a
36delegate which provides a template for constructing items in the view.
37
38The code for the ListView and delegate looks like this:
39
40\snippet tutorials/dynamicview/dynamicview1/dynamicview.qml 0
41
42The model is defined in a separate QML file which looks like this:
43
44\snippet tutorials/dynamicview/dynamicview1/PetsModel.qml 0
45\snippet tutorials/dynamicview/dynamicview1/PetsModel.qml 1
46
47\section2 Walkthrough
48
49The first item defined within the application's root Rectangle is the delegate Component. This
50is the template from which each item in the ListView is constructed.
51
52The \c name, \c age, \c type, and \c size variables referenced in the delegate are sourced from
53the model data. The names correspond to roles defined in the model.
54
55\snippet tutorials/dynamicview/dynamicview1/dynamicview.qml 1
56
57The second part of the application is the ListView itself to which we bind the model and delegate.
58
59\snippet tutorials/dynamicview/dynamicview1/dynamicview.qml 2
60*/
61
62/*!
63\title QML Dynamic View Ordering Tutorial 2 - Dragging View Items
64\previouspage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
65\nextpage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
66
67\example tutorials/dynamicview/dynamicview2
68
69Now that we have a visible list of items we want to be able to interact with them. We'll start
70by extending the delegate so the visible content can be dragged up and down the screen. The
71updated delegate looks like this:
72
73\snippet tutorials/dynamicview/dynamicview2/dynamicview.qml 0
74
75\section2 Walkthrough
76
77The major change here is the root item of the delegate is now a MouseArea which provides handlers
78for mouse events and will allow us to drag the delegate's content item. It also acts as
79a container for the content item which is important as a delegate's root item is positioned by
80the view and cannot be moved by other means.
81
82\snippet tutorials/dynamicview/dynamicview2/dynamicview.qml 1
83\snippet tutorials/dynamicview/dynamicview2/dynamicview.qml 2
84
85Dragging the content item is enabled by binding it to the MouseArea's
86\l {QtQuick::MouseArea::drag.target}{drag.target} property. Because we still want the view to be
87flickable we wait until the MouseArea's \l {QtQuick::MouseArea::}{pressAndHold}
88signal is emitted before binding the drag target. This way when mouse moves before the hold
89timeout has expired it is interpreted as moving the list and if it moves after it is interpreted as
90dragging an item. To make it more obvious to the user when an item can be dragged we'll change the
91background color of the content item when the timeout has expired.
92
93\snippet tutorials/dynamicview/dynamicview2/dynamicview.qml 3
94
95The other thing we'll need to do before an item can be dragged is to unset any anchors on the
96content item so it can be freely moved around. We do this in a state change that is triggered
97when the delegate item is held, at the same time we can reparent the content item to the root item
98so that is above other items in the stacking order and isn't obscured as it is dragged around.
99
100\snippet tutorials/dynamicview/dynamicview2/dynamicview.qml 4
101
102*/
103
104/*!
105\title QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
106\previouspage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
107\nextpage QML Dynamic View Ordering Tutorial 4 - Sorting Items
108
109\example tutorials/dynamicview/dynamicview3
110
111The next step in our application to move items within the list as they're dragged so that we
112can re-order the list. To achieve this we introduce three new types to our application;
113DelegateModel, \l Drag and DropArea.
114
115\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 0
116\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 1
117\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 2
118\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 5
119
120\section2 Walkthrough
121
122In order to re-order the view we need to determine when one item has been dragged over another. With
123the Drag attached property we can generate events that are sent to the scene graph whenever the item
124it is attached to moves.
125
126\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 1
127
128Drag events are only sent while the active property is true, so in this example the first event
129would be sent when the delegate was held with additional event sents when dragging. The
130\l {QtQuick::Drag::hotSpot}{hotSpot} property specifies the relative position of the drag events
131within the dragged item, the center of the item in this instance.
132
133Then we use a DropArea in each view item to determine when the hot spot of the dragged item
134intersects another item, when a drag enters one of these DropAreas we can move the dragged item
135to the index of the item it was dragged over.
136
137\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 3
138
139To move the items within the view we use a DelegateModel. The DelegateModel type is used by
140the view types to instantiate delegate items from model data and when constructed explicitly can
141be used to filter and re-order the model items provided to ListView. The
142\l [QML]{DelegateModel::}{items} property of DelegateModel provides access to the
143view's items and allows us to change the visible order without modifying the source model. To
144determine the current visible index of the items we use \l {DelegateModel::}{itemsIndex}
145{itemsIndex} property on the DelegateModel attached property of the delegate item.
146
147To utilize a DelegateModel with a ListView we bind it to the \l {ListView::}{model}
148property of the view and bind the \l {DelegateModel::}{model} and
149\l {DelegateModel::}{delegate} to the DelegateModel.
150
151\snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 4
152
153*/
154
155/*!
156\title QML Dynamic View Ordering Tutorial 4 - Sorting Items
157\previouspage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
158
159\example tutorials/dynamicview/dynamicview4
160
161Drag and drop isn't the only way items in a view can be re-ordered, using a DelegateModel it is
162also possible to sort items based on model data. To do that we extend our DelegateModel instance
163like this:
164
165\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 0
166
167\section2 Walkthrough
168
169Items in a DelegateModel are filtered into groups represented by the DelegateModelGroup type,
170normally all items in the model belong to a default \l {DelegateModel::}{items}
171group but this default can be changed with the includeByDefault property. To implement our sorting
172we want items to first be added to an unsorted group from where we can transfer them to a sorted
173position in the items group. To do that we clear includeByDefault on the items group and set it on
174a new group name 'unsorted'.
175
176\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 1
177\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 2
178
179We sort the items by first finding the position in the items group to insert the first unsorted
180item and then transfer the item to the items group before moving it to the pre-determined index and
181repeat until the unsorted group is empty.
182
183To find the insert position for an item we request a handle for the item from the unsorted group
184with the \l {DelegateModelGroup::}{get()} function. Through the model property on this handle we can
185access the same model data that is available in a delegate instance of that item and
186compare against other items to determine relative position.
187
188\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 3
189
190The lessThan argument to the sort function is a comparsion function which will determine the order
191of the list. In this example it can be one of the following:
192
193\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 4
194
195A sort is triggered whenever new items are added to the unsorted DelegateModel which we are
196notified of by the \l {DelegateModelGroup} \c onChanged handler. If no sort
197function is currently selected we simply transfer all items from the unsorted group to the items
198group, otherwise we call sort with the selected sort function.
199
200\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 5
201
202Finally when the selected sort order changes we can trigger a full re-sort of the list by moving
203all items from the items group to the unsorted group, which will trigger the
204\l {DelegateModelGroup} \c onChanged handler and transfer the items back to the
205items group in correct order. Note that the \l {DelegateModelGroup} \c onChanged
206handler will not be invoked recursively so there's no issue with it being invoked during a sort.
207
208\snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 6
209
210*/