diff options
Diffstat (limited to 'doc/src/examples/editabletreemodel.qdoc')
-rw-r--r-- | doc/src/examples/editabletreemodel.qdoc | 446 |
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 - -*/ |