source: trunk/doc/src/examples/simpletreemodel.qdoc@ 357

Last change on this file since 357 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 15.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example itemviews/simpletreemodel
44 \title Simple Tree Model Example
45
46 The Simple Tree Model example shows how to create a basic, read-only
47 hierarchical model to use with Qt's standard view classes. For a
48 description of simple non-hierarchical list and table models, see the
49 \l{model-view-programming.html}{Model/View Programming} overview.
50
51 \image simpletreemodel-example.png
52
53 Qt's model/view architecture provides a standard way for views to manipulate
54 information in a data source, using an abstract model of the data to
55 simplify and standardize the way it is accessed. Simple models represent
56 data as a table of items, and allow views to access this data via an
57 \l{model-view-model.html}{index-based} system. More generally, models can
58 be used to represent data in the form of a tree structure by allowing each
59 item to act as a parent to a table of child items.
60
61 Before attempting to implement a tree model, it is worth considering whether
62 the data is supplied by an external source, or whether it is going to be
63 maintained within the model itself. In this example, we will implement an
64 internal structure to hold data rather than discuss how to package data from
65 an external source.
66
67 \section1 Design and Concepts
68
69 The data structure that we use to represent the structure of the data takes
70 the form of a tree built from \c TreeItem objects. Each \c TreeItem
71 represents an item in a tree view, and contains several columns of data.
72
73 \target SimpleTreeModelStructure
74 \table
75 \row \i \inlineimage treemodel-structure.png
76 \i \bold{Simple Tree Model Structure}
77
78 The data is stored internally in the model using \c TreeItem objects that
79 are linked together in a pointer-based tree structure. Generally, each
80 \c TreeItem has a parent item, and can have a number of child items.
81 However, the root item in the tree structure has no parent item and it
82 is never referenced outside the model.
83
84 Each \c TreeItem contains information about its place in the tree
85 structure; it can return its parent item and its row number. Having
86 this information readily available makes implementing the model easier.
87
88 Since each item in a tree view usually contains several columns of data
89 (a title and a summary in this example), it is natural to store this
90 information in each item. For simplicity, we will use a list of QVariant
91 objects to store the data for each column in the item.
92 \endtable
93
94 The use of a pointer-based tree structure means that, when passing a
95 model index to a view, we can record the address of the corresponding
96 item in the index (see QAbstractItemModel::createIndex()) and retrieve
97 it later with QModelIndex::internalPointer(). This makes writing the
98 model easier and ensures that all model indexes that refer to the same
99 item have the same internal data pointer.
100
101 With the appropriate data structure in place, we can create a tree model
102 with a minimal amount of extra code to supply model indexes and data to
103 other components.
104
105 \section1 TreeItem Class Definition
106
107 The \c TreeItem class is defined as follows:
108
109 \snippet examples/itemviews/simpletreemodel/treeitem.h 0
110
111 The class is a basic C++ class. It does not inherit from QObject or
112 provide signals and slots. It is used to hold a list of QVariants,
113 containing column data, and information about its position in the tree
114 structure. The functions provide the following features:
115
116 \list
117 \o The \c appendChildItem() is used to add data when the model is first
118 constructed and is not used during normal use.
119 \o The \c child() and \c childCount() functions allow the model to obtain
120 information about any child items.
121 \o Information about the number of columns associated with the item is
122 provided by \c columnCount(), and the data in each column can be
123 obtained with the data() function.
124 \o The \c row() and \c parent() functions are used to obtain the item's
125 row number and parent item.
126 \endlist
127
128 The parent item and column data are stored in the \c parentItem and
129 \c itemData private member variables. The \c childItems variable contains
130 a list of pointers to the item's own child items.
131
132 \section1 TreeItem Class Implementation
133
134 The constructor is only used to record the item's parent and the data
135 associated with each column.
136
137 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 0
138
139 A pointer to each of the child items belonging to this item will be
140 stored in the \c childItems private member variable. When the class's
141 destructor is called, it must delete each of these to ensure that
142 their memory is reused:
143
144 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 1
145
146 Since each of the child items are constructed when the model is initially
147 populated with data, the function to add child items is straightforward:
148
149 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 2
150
151 Each item is able to return any of its child items when given a suitable
152 row number. For example, in the \l{#SimpleTreeModelStructure}{above diagram},
153 the item marked with the letter "A" corresponds to the child of the root item
154 with \c{row = 0}, the "B" item is a child of the "A" item with \c{row = 1},
155 and the "C" item is a child of the root item with \c{row = 1}.
156
157 The \c child() function returns the child that corresponds to
158 the specified row number in the item's list of child items:
159
160 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 3
161
162 The number of child items held can be found with \c childCount():
163
164 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 4
165
166 The \c TreeModel uses this function to determine the number of rows that
167 exist for a given parent item.
168
169 The \c row() function reports the item's location within its parent's
170 list of items:
171
172 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 8
173
174 Note that, although the root item (with no parent item) is automatically
175 assigned a row number of 0, this information is never used by the model.
176
177 The number of columns of data in the item is trivially returned by the
178 \c columnCount() function.
179
180 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 5
181
182 Column data is returned by the \c data() function, taking advantage of
183 QList's ability to provide sensible default values if the column number
184 is out of range:
185
186 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 6
187
188 The item's parent is found with \c parent():
189
190 \snippet examples/itemviews/simpletreemodel/treeitem.cpp 7
191
192 Note that, since the root item in the model will not have a parent, this
193 function will return zero in that case. We need to ensure that the model
194 handles this case correctly when we implement the \c TreeModel::parent()
195 function.
196
197 \section1 TreeModel Class Definition
198
199 The \c TreeModel class is defined as follows:
200
201 \snippet examples/itemviews/simpletreemodel/treemodel.h 0
202
203 This class is similar to most other subclasses of QAbstractItemModel that
204 provide read-only models. Only the form of the constructor and the
205 \c setupModelData() function are specific to this model. In addition, we
206 provide a destructor to clean up when the model is destroyed.
207
208 \section1 TreeModel Class Implementation
209
210 For simplicity, the model does not allow its data to be edited. As a
211 result, the constructor takes an argument containing the data that the
212 model will share with views and delegates:
213
214 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 0
215
216 It is up to the constructor to create a root item for the model. This
217 item only contains vertical header data for convenience. We also use it
218 to reference the internal data structure that contains the model data,
219 and it is used to represent an imaginary parent of top-level items in
220 the model.
221
222 The model's internal data structure is populated with items by the
223 \c setupModelData() function. We will examine this function separately
224 at the end of this document.
225
226 The destructor ensures that the root item and all of its descendants
227 are deleted when the model is destroyed:
228
229 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 1
230
231 Since we cannot add data to the model after it is constructed and set
232 up, this simplifies the way that the internal tree of items is managed.
233
234 Models must implement an \c index() function to provide indexes for
235 views and delegates to use when accessing data. Indexes are created
236 for other components when they are referenced by their row and column
237 numbers, and their parent model index. If an invalid model
238 index is specified as the parent, it is up to the model to return an
239 index that corresponds to a top-level item in the model.
240
241 When supplied with a model index, we first check whether it is valid.
242 If it is not, we assume that a top-level item is being referred to;
243 otherwise, we obtain the data pointer from the model index with its
244 \l{QModelIndex::internalPointer()}{internalPointer()} function and use
245 it to reference a \c TreeItem object. Note that all the model indexes
246 that we construct will contain a pointer to an existing \c TreeItem,
247 so we can guarantee that any valid model indexes that we receive will
248 contain a valid data pointer.
249
250 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 6
251
252 Since the row and column arguments to this function refer to a
253 child item of the corresponding parent item, we obtain the item using
254 the \c TreeItem::child() function. The
255 \l{QAbstractItemModel::createIndex()}{createIndex()} function is used
256 to create a model index to be returned. We specify the row and column
257 numbers, and a pointer to the item itself. The model index can be used
258 later to obtain the item's data.
259
260 The way that the \c TreeItem objects are defined makes writing the
261 \c parent() function easy:
262
263 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 7
264
265 We only need to ensure that we never return a model index corresponding
266 to the root item. To be consistent with the way that the \c index()
267 function is implemented, we return an invalid model index for the
268 parent of any top-level items in the model.
269
270 When creating a model index to return, we must specify the row and
271 column numbers of the parent item within its own parent. We can
272 easily discover the row number with the \c TreeItem::row() function,
273 but we follow a convention of specifying 0 as the column number of
274 the parent. The model index is created with
275 \l{QAbstractItemModel::createIndex()}{createIndex()} in the same way
276 as in the \c index() function.
277
278 The \c rowCount() function simply returns the number of child items
279 for the \c TreeItem that corresponds to a given model index, or the
280 number of top-level items if an invalid index is specified:
281
282 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 8
283
284 Since each item manages its own column data, the \c columnCount()
285 function has to call the item's own \c columnCount() function to
286 determine how many columns are present for a given model index.
287 As with the \c rowCount() function, if an invalid model index is
288 specified, the number of columns returned is determined from the
289 root item:
290
291 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 2
292
293 Data is obtained from the model via \c data(). Since the item manages
294 its own columns, we need to use the column number to retrieve the data
295 with the \c TreeItem::data() function:
296
297 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 3
298
299 Note that we only support the \l{Qt::ItemDataRole}{DisplayRole}
300 in this implementation, and we also return invalid QVariant objects for
301 invalid model indexes.
302
303 We use the \c flags() function to ensure that views know that the
304 model is read-only:
305
306 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 4
307
308 The \c headerData() function returns data that we conveniently stored
309 in the root item:
310
311 \snippet examples/itemviews/simpletreemodel/treemodel.cpp 5
312
313 This information could have been supplied in a different way: either
314 specified in the constructor, or hard coded into the \c headerData()
315 function.
316
317 \section1 Setting Up the Data in the Model
318
319 We use the \c setupModelData() function to set up the initial data in
320 the model. This function parses a text file, extracting strings of
321 text to use in the model, and creates item objects that record both
322 the data and the overall model structure.
323 Naturally, this function works in a way that is very specific to
324 this model. We provide the following description of its behavior,
325 and refer the reader to the example code itself for more information.
326
327 We begin with a text file in the following format:
328
329 \snippet doc/src/snippets/code/doc_src_examples_simpletreemodel.qdoc 0
330 \dots
331 \snippet doc/src/snippets/code/doc_src_examples_simpletreemodel.qdoc 1
332
333 We process the text file with the following two rules:
334
335 \list
336 \o For each pair of strings on each line, create an item (or node)
337 in a tree structure, and place each string in a column of data
338 in the item.
339 \o When the first string on a line is indented with respect to the
340 first string on the previous line, make the item a child of the
341 previous item created.
342 \endlist
343
344 To ensure that the model works correctly, it is only necessary to
345 create instances of \c TreeItem with the correct data and parent item.
346*/
Note: See TracBrowser for help on using the repository browser.