summaryrefslogtreecommitdiffstats
path: root/doc/src/examples/editabletreemodel.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/examples/editabletreemodel.qdoc')
-rw-r--r--doc/src/examples/editabletreemodel.qdoc446
1 files changed, 0 insertions, 446 deletions
diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc
deleted file mode 100644
index 958080ad58..0000000000
--- a/doc/src/examples/editabletreemodel.qdoc
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** GNU Free Documentation License
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms
-** and conditions contained in a signed written agreement between you
-** and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example itemviews/editabletreemodel
- \title Editable Tree Model Example
-
- This example shows how to implement a simple item-based tree model that can
- be used with other classes the model/view framework.
-
- \image itemviews-editabletreemodel.png
-
- The model supports editable items, custom headers, and the ability to
- insert and remove rows and columns. With these features, it is also
- possible to insert new child items, and this is shown in the supporting
- example code.
-
- \note The model only shows the basic principles used when creating an
- editable, hierarchical model. You may wish to use the \l{ModelTest}
- project to test production models.
-
- \section1 Overview
-
- As described in the \l{Model Subclassing Reference}, models must
- provide implementations for the standard set of model functions:
- \l{QAbstractItemModel::}{flags()}, \l{QAbstractItemModel::}{data()},
- \l{QAbstractItemModel::}{headerData()},
- \l{QAbstractItemModel::}{columnCount()}, and
- \l{QAbstractItemModel::}{rowCount()}. In addition, hierarchical models,
- such as this one, need to provide implementations of
- \l{QAbstractItemModel::}{index()} and \l{QAbstractItemModel::}{parent()}.
-
- An editable model needs to provide implementations of
- \l{QAbstractItemModel::}{setData()} and
- \l{QAbstractItemModel::}{setHeaderData()}, and must return a suitable
- combination of flags from its \l{QAbstractItemModel::}{flags()} function.
-
- Since this example allows the dimensions of the model to be changed,
- we must also implement \l{QAbstractItemModel::}{insertRows()},
- \l{QAbstractItemModel::}{insertColumns()},
- \l{QAbstractItemModel::}{removeRows()}, and
- \l{QAbstractItemModel::}{removeColumns()}.
-
- \section1 Design
-
- As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
- the model simply acts as a wrapper around a collection
- of instances of a \c TreeItem class. Each \c TreeItem is designed to
- hold data for a row of items in a tree view, so it contains a list of
- values corresponding to the data shown in each column.
-
- Since QTreeView provides a row-oriented view onto a model, it is
- natural to choose a row-oriented design for data structures that
- will supply data via a model to this kind of view. Although this makes
- the tree model less flexible, and possibly less useful for use with
- more sophisticated views, it makes it less complex to design and easier
- to implement.
-
- \target Relations-between-internal-items
- \table
- \row \li \inlineimage itemviews-editabletreemodel-items.png
- \li \b{Relations between internal items}
-
- When designing a data structure for use with a custom model, it is useful
- to expose each item's parent via a function like
- \l{TreeItem::parent}{TreeItem::parent()} because it will make
- writing the model's own \l{QAbstractItemModel::}{parent()} function easier.
- Similarly, a function like \l{TreeItem::child}{TreeItem::child()} is
- helpful when implementing the model's \l{QAbstractItemModel::}{index()}
- function. As a result, each \c TreeItem maintains information about
- its parent and children, making it possible for us to traverse the tree
- structure.
-
- The diagram shows how \c TreeItem instances are connected via their
- \l{TreeItem::parent}{parent()} and \l{TreeItem::child}{child()}
- functions.
-
- In the example shown, two top-level items, \b{A} and
- \b{B}, can be obtained from the root item by calling its child()
- function, and each of these items return the root node from their
- parent() functions, though this is only shown for item \b{A}.
- \endtable
-
- Each \c TreeItem stores data for each column in the row it represents
- in its \c itemData private member (a list of QVariant objects).
- Since there is a one-to-one mapping between each column in the view
- and each entry in the list, we provide a simple
- \l{TreeItem::data}{data()} function to read entries in the \c itemData
- list and a \l{TreeItem::setData}{setData()} function to allow them to
- be modified.
- As with other functions in the item, this simplifies the implemention
- of the model's \l{QAbstractItemModel::}{data()} and
- \l{QAbstractItemModel::}{setData()} functions.
-
- We place an item at the root of the tree of items. This root item
- corresponds to the null model index, \l{QModelIndex::}{QModelIndex()},
- that is used to represent the parent of a top-level item when handling
- model indexes.
- Although the root item does not have a visible representation in any of
- the standard views, we use its internal list of QVariant objects to
- store a list of strings that will be passed to views for use as
- horizontal header titles.
-
- \table
- \row \li \inlineimage itemviews-editabletreemodel-model.png
- \li \b{Accessing data via the model}
-
- In the case shown in the diagram, the piece of information represented
- by \b{a} can be obtained using the standard model/view API:
-
- \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 0
-
- Since each items holds pieces of data for each column in a given row,
- there can be many model indexes that map to the same \c TreeItem object.
- For example, the information represented by \b{b} can be obtained
- using the following code:
-
- \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 1
-
- The same underlying \c TreeItem would be accessed to obtain information
- for the other model indexes in the same row as \b{b}.
- \endtable
-
- In the model class, \c TreeModel, we relate \c TreeItem objects to
- model indexes by passing a pointer for each item when we create its
- corresponding model index with QAbstractItemModel::createIndex() in
- our \l{TreeModel::index}{index()} and \l{TreeModel::parent}{parent()}
- implementations.
- We can retrieve pointers stored in this way by calling the
- \l{QModelIndex::}{internalPointer()} function on the relevant model
- index - we create our own \l{TreeModel::getItem}{getItem()} function to
- do this work for us, and call it from our \l{TreeModel::data}{data()}
- and \l{TreeModel::parent}{parent()} implementations.
-
- Storing pointers to items is convenient when we control how they are
- created and destroyed since we can assume that an address obtained from
- \l{QModelIndex::}{internalPointer()} is a valid pointer.
- However, some models need to handle items that are obtained from other
- components in a system, and in many cases it is not possible to fully
- control how items are created or destroyed. In such situations, a pure
- pointer-based approach needs to be supplemented by safeguards to ensure
- that the model does not attempt to access items that have been deleted.
-
- \table
- \row \li \b{Storing information in the underlying data structure}
-
- Several pieces of data are stored as QVariant objects in the \c itemData
- member of each \c TreeItem instance
-
- The diagram shows how pieces of information,
- represented by the labels \b{a}, \b{b} and \b{c} in the
- previous two diagrams, are stored in items \b{A}, \b{B} and
- \b{C} in the underlying data structure. Note that pieces of
- information from the same row in the model are all obtained from the
- same item. Each element in a list corresponds to a piece of information
- exposed by each column in a given row in the model.
-
- \li \inlineimage itemviews-editabletreemodel-values.png
- \endtable
-
- Since the \c TreeModel implementation has been designed for use with
- QTreeView, we have added a restriction on the way it uses \c TreeItem
- instances: each item must expose the same number of columns of data.
- This makes viewing the model consistent, allowing us to use the root
- item to determine the number of columns for any given row, and only
- adds the requirement that we create items containing enough data for
- the total number of columns. As a result, inserting and removing
- columns are time-consuming operations because we need to traverse the
- entire tree to modify every item.
-
- An alternative approach would be to design the \c TreeModel class so
- that it truncates or expands the list of data in individual \c TreeItem
- instances as items of data are modified. However, this "lazy" resizing
- approach would only allow us to insert and remove columns at the end of
- each row and would not allow columns to be inserted or removed at
- arbitrary positions in each row.
-
- \target Relating-items-using-model-indexes
- \table
- \row
- \li \inlineimage itemviews-editabletreemodel-indexes.png
- \li \b{Relating items using model indexes}
-
- As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
- the \c TreeModel needs to be able to take a model index, find the
- corresponding \c TreeItem, and return model indexes that correspond to
- its parents and children.
-
- In the diagram, we show how the model's \l{TreeModel::parent}{parent()}
- implementation obtains the model index corresponding to the parent of
- an item supplied by the caller, using the items shown in a
- \l{Relations-between-internal-items}{previous diagram}.
-
- A pointer to item \b{C} is obtained from the corresponding model index
- using the \l{QModelIndex::internalPointer()} function. The pointer was
- stored internally in the index when it was created. Since the child
- contains a pointer to its parent, we use its \l{TreeItem::parent}{parent()}
- function to obtain a pointer to item \b{B}. The parent model index is
- created using the QAbstractItemModel::createIndex() function, passing
- the pointer to item \b{B} as the internal pointer.
- \endtable
-
- \section1 TreeItem Class Definition
-
- The \c TreeItem class provides simple items that contain several
- pieces of data, and which can provide information about their parent
- and child items:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.h 0
-
- We have designed the API to be similar to that provided by
- QAbstractItemModel by giving each item functions to return the number
- of columns of information, read and write data, and insert and remove
- columns. However, we make the relationship between items explicit by
- providing functions to deal with "children" rather than "rows".
-
- Each item contains a list of pointers to child items, a pointer to its
- parent item, and a list of QVariant objects that correspond to
- information held in columns in a given row in the model.
-
- \section1 TreeItem Class Implementation
-
- Each \c TreeItem is constructed with a list of data and an optional
- parent item:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 0
-
- Initially, each item has no children. These are added to the item's
- internal \c childItems member using the \c insertChildren() function
- described later.
-
- The destructor ensures that each child added to the item is deleted
- when the item itself is deleted:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 1
-
- \target TreeItem::parent
- Since each item stores a pointer to its parent, the \c parent() function
- is trivial:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 9
-
- \target TreeItem::child
- Three functions provide information about the children of an item.
- \c child() returns a specific child from the internal list of children:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 2
-
- The \c childCount() function returns the total number of children:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 3
-
- The \c childNumber() function is used to determine the index of the child
- in its parent's list of children. It accesses the parent's \c childItems
- member directly to obtain this information:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 4
-
- The root item has no parent item; for this item, we return zero to be
- consistent with the other items.
-
- The \c columnCount() function simply returns the number of elements in
- the internal \c itemData list of QVariant objects:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 5
-
- \target TreeItem::data
- Data is retrieved using the \c data() function, which accesses the
- appropriate element in the \c itemData list:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 6
-
- \target TreeItem::setData
- Data is set using the \c setData() function, which only stores values
- in the \c itemData list for valid list indexes, corresponding to column
- values in the model:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 11
-
- To make implementation of the model easier, we return true to indicate
- whether the data was set successfully, or false if an invalid column
-
- Editable models often need to be resizable, enabling rows and columns to
- be inserted and removed. The insertion of rows beneath a given model index
- in the model leads to the insertion of new child items in the corresponding
- item, handled by the \c insertChildren() function:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 7
-
- This ensures that new items are created with the required number of columns
- and inserted at a valid position in the internal \c childItems list.
- Items are removed with the \c removeChildren() function:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 10
-
- As discussed above, the functions for inserting and removing columns are
- used differently to those for inserting and removing child items because
- they are expected to be called on every item in the tree. We do this by
- recursively calling this function on each child of the item:
-
- \snippet examples/itemviews/editabletreemodel/treeitem.cpp 8
-
- \section1 TreeModel Class Definition
-
- The \c TreeModel class provides an implementation of the QAbstractItemModel
- class, exposing the necessary interface for a model that can be edited and
- resized.
-
- \snippet examples/itemviews/editabletreemodel/treemodel.h 0
-
- The constructor and destructor are specific to this model.
-
- \snippet examples/itemviews/editabletreemodel/treemodel.h 1
-
- Read-only tree models only need to provide the above functions. The
- following public functions provide support for editing and resizing:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.h 2
-
- To simplify this example, the data exposed by the model is organized into
- a data structure by the model's \l{TreeModel::setupModelData}{setupModelData()}
- function. Many real world models will not process the raw data at all, but
- simply work with an existing data structure or library API.
-
- \section1 TreeModel Class Implementation
-
- The constructor creates a root item and initializes it with the header
- data supplied:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 0
-
- We call the internal \l{TreeModel::setupModelData}{setupModelData()}
- function to convert the textual data supplied to a data structure we can
- use with the model. Other models may be initialized with a ready-made
- data structure, or use an API to a library that maintains its own data.
-
- The destructor only has to delete the root item; all child items will
- be recursively deleted by the \c TreeItem destructor.
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 1
-
- \target TreeModel::getItem
- Since the model's interface to the other model/view components is based
- on model indexes, and the internal data structure is item-based, many of
- the functions implemented by the model need to be able to convert any
- given model index to its corresponding item. For convenience and
- consistency, we have defined a \c getItem() function to perform this
- repetitive task:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 4
-
- This function assumes that each model index it is passed corresponds to
- a valid item in memory. If the index is invalid, or its internal pointer
- does not refer to a valid item, the root item is returned instead.
-
- The model's \c rowCount() implementation is simple: it first uses the
- \c getItem() function to obtain the relevant item, then returns the
- number of children it contains:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 8
-
- By contrast, the \c columnCount() implementation does not need to look
- for a particular item because all items are defined to have the same
- number of columns associated with them.
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 2
-
- As a result, the number of columns can be obtained directly from the root
- item.
-
- To enable items to be edited and selected, the \c flags() function needs
- to be implemented so that it returns a combination of flags that includes
- the Qt::ItemIsEditable and Qt::ItemIsSelectable flags as well as
- Qt::ItemIsEnabled:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 3
-
- \target TreeModel::index
- The model needs to be able to generate model indexes to allow other
- components to request data and information about its structure. This task
- is performed by the \c index() function, which is used to obtain model
- indexes corresponding to children of a given parent item:
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 5
-
- In this model, we only return model indexes for child items if the parent
- index is invalid (corresponding to the root item) or if it has a zero
- column number.
-
- We use the custom \l{TreeModel::getItem}{getItem()} function to obtain
- a \c TreeItem instance that corresponds to the model index supplied, and
- request its child item that corresponds to the specified row.
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 6
-
- Since each item contains information for an entire row of data, we create
- a model index to uniquely identify it by calling
- \l{QAbstractItemModel::}{createIndex()} it with the row and column numbers
- and a pointer to the item. In the \l{TreeModel::data}{data()} function,
- we will use the item pointer and column number to access the data
- associated with the model index; in this model, the row number is not
- needed to identify data.
-
- \target TreeModel::parent
- The \c parent() function supplies model indexes for parents of items
- by finding the corresponding item for a given model index, using its
- \l{TreeItem::parent}{parent()} function to obtain its parent item,
- then creating a model index to represent the parent. (See
- \l{Relating-items-using-model-indexes}{the above diagram}).
-
- \snippet examples/itemviews/editabletreemodel/treemodel.cpp 7
-
- Items without parents, including the root item, are handled by returning
- a null model index. Otherwise, a model index is created and returned as
- in the \l{TreeModel::index}{index()} function, with a suitable row number,
- but with a zero column number to be consistent with the scheme used in
- the \l{TreeModel::index}{index()} implementation.
-
- \target TreeModel::data
- \target TreeModel::setupModelData
-
-*/