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