doc/src/examples/simpletreemodel.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 */