| 1 | /****************************************************************************
|
|---|
| 2 | **
|
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 | ** All rights reserved.
|
|---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
|---|
| 6 | **
|
|---|
| 7 | ** This file is part of the documentation of the Qt Toolkit.
|
|---|
| 8 | **
|
|---|
| 9 | ** $QT_BEGIN_LICENSE:FDL$
|
|---|
| 10 | ** Commercial Usage
|
|---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
|---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
|---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in a
|
|---|
| 14 | ** written agreement between you and Nokia.
|
|---|
| 15 | **
|
|---|
| 16 | ** GNU Free Documentation License
|
|---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Free
|
|---|
| 18 | ** Documentation License version 1.3 as published by the Free Software
|
|---|
| 19 | ** Foundation and appearing in the file included in the packaging of this
|
|---|
| 20 | ** file.
|
|---|
| 21 | **
|
|---|
| 22 | ** If you have questions regarding the use of this file, please contact
|
|---|
| 23 | ** Nokia at [email protected].
|
|---|
| 24 | ** $QT_END_LICENSE$
|
|---|
| 25 | **
|
|---|
| 26 | ****************************************************************************/
|
|---|
| 27 |
|
|---|
| 28 | /*!
|
|---|
| 29 | \page qt4-interview.html
|
|---|
| 30 | \title The Interview Framework
|
|---|
| 31 |
|
|---|
| 32 | \contentspage {What's New in Qt 4}{Home}
|
|---|
| 33 | \previouspage The Tulip Container Classes
|
|---|
| 34 | \nextpage The Arthur Paint System
|
|---|
| 35 |
|
|---|
| 36 | The Interview classes provide a model/view framework for Qt
|
|---|
| 37 | applications based on the well known Model-View-Controller design
|
|---|
| 38 | pattern. In this document, we will describe Qt's model/view
|
|---|
| 39 | architecture, provide some examples, and show the improvements
|
|---|
| 40 | offered over Qt 3's item view classes.
|
|---|
| 41 |
|
|---|
| 42 | \tableofcontents
|
|---|
| 43 |
|
|---|
| 44 | \section1 Overview of The Model/View Architecture
|
|---|
| 45 |
|
|---|
| 46 | The model/view architecture is a variation of the Model-View-Controller
|
|---|
| 47 | (MVC) design pattern, originating from Smalltalk, that is often used when
|
|---|
| 48 | building user interfaces.
|
|---|
| 49 |
|
|---|
| 50 | In the model/view architecture, the view and the controller objects are
|
|---|
| 51 | combined. This still separates the way that data is stored from the way
|
|---|
| 52 | that it is presented to the user, but provides a simpler framework based
|
|---|
| 53 | on the same principles. This separation makes it possible to display the
|
|---|
| 54 | same data in several different views, and to implement new types of views,
|
|---|
| 55 | without changing the underlying data structures.
|
|---|
| 56 |
|
|---|
| 57 | User input is handled by \e delegates. The advantage of this approach is
|
|---|
| 58 | that it allows rendering and editing of individual items of data to be
|
|---|
| 59 | customized to suit each data type in use.
|
|---|
| 60 |
|
|---|
| 61 | \table
|
|---|
| 62 | \row \i \inlineimage modelview-overview.png
|
|---|
| 63 | \i \bold{The model/view architecture}
|
|---|
| 64 |
|
|---|
| 65 | The model communicates with a source of data, providing an \e interface
|
|---|
| 66 | for the other components in the architecture. The nature of the
|
|---|
| 67 | communication depends on the type of data source, and the way the model
|
|---|
| 68 | is implemented.
|
|---|
| 69 |
|
|---|
| 70 | The view obtains \e{model indexes} from the model; these are references
|
|---|
| 71 | to items of data. By supplying model indexes to the model, the view can
|
|---|
| 72 | retrieve items of data from the data source.
|
|---|
| 73 |
|
|---|
| 74 | In standard views, a \e delegate renders the items of data. When an item
|
|---|
| 75 | is edited, the delegate communicates with the model directly using
|
|---|
| 76 | model indexes.
|
|---|
| 77 | \endtable
|
|---|
| 78 |
|
|---|
| 79 | \section1 Model/View Classes
|
|---|
| 80 |
|
|---|
| 81 | On a fundamental level, the Interview classes define the interfaces and
|
|---|
| 82 | common functionality for models, views, and delegates. All implemented
|
|---|
| 83 | components subclass QAbstractItemModel, QAbstractItemView, or
|
|---|
| 84 | QAbstractItemDelegate. The use of a common API ensures a level of
|
|---|
| 85 | interoperability between the components.
|
|---|
| 86 |
|
|---|
| 87 | \image standard-views.png
|
|---|
| 88 |
|
|---|
| 89 | Interview provides ready-to-use implementations of views for table,
|
|---|
| 90 | tree, and list widgets: QTableView, QTreeView, and QListView.
|
|---|
| 91 | These standard views are suitable for displaying the most common
|
|---|
| 92 | types of data structures used in applications, and can be used with
|
|---|
| 93 | the ready-made models supplied with Qt:
|
|---|
| 94 |
|
|---|
| 95 | \list
|
|---|
| 96 | \o QStandardItemModel is a minimal convenience model that developers
|
|---|
| 97 | can use to manage items of data.
|
|---|
| 98 | \o QFileSystemModel provides directory information for use with QListView
|
|---|
| 99 | and QTreeView.
|
|---|
| 100 | \o QStringListModel is a convenience model that can be used to hold
|
|---|
| 101 | strings for views such as QListView and QComboBox.
|
|---|
| 102 | \endlist
|
|---|
| 103 |
|
|---|
| 104 | Two specialized abstract models are provided that can be subclassed
|
|---|
| 105 | and extended (see the
|
|---|
| 106 | \l{model-view-programming.html#related-examples}{Model/View Programming}
|
|---|
| 107 | examples):
|
|---|
| 108 |
|
|---|
| 109 | \list
|
|---|
| 110 | \o QAbstractTableModel is a useful starting point for providing a custom
|
|---|
| 111 | model that can be used with QTableView.
|
|---|
| 112 | \o QAbstractListModel can be subclassed to produce a list-based model
|
|---|
| 113 | for use with QListView.
|
|---|
| 114 | \endlist
|
|---|
| 115 |
|
|---|
| 116 | Operations on items, such as filtering and sorting, are handled by \e{proxy
|
|---|
| 117 | models} that allow views to display processed data without having to
|
|---|
| 118 | copy or modify data obtained from a source model. Interview provides
|
|---|
| 119 | the QSortFilterProxyModel class to allow items of data from a source model
|
|---|
| 120 | to be sorted and filtered before they are supplied to views.
|
|---|
| 121 |
|
|---|
| 122 | Developers who are familiar with the conventional list, tree, and table
|
|---|
| 123 | widgets may find QListWidget, QTreeWidget, and QTableWidget useful.
|
|---|
| 124 | These present a simplified interface to the views that does not require a
|
|---|
| 125 | knowledge of the underlying model/view architecture.
|
|---|
| 126 |
|
|---|
| 127 | For details about how to use the model/view classes, see the
|
|---|
| 128 | \l{Model/View Programming} document.
|
|---|
| 129 |
|
|---|
| 130 | See also the \l{The Qt 4 Database GUI Layer}{Database GUI Layer} document
|
|---|
| 131 | for information about Qt 4's database models.
|
|---|
| 132 |
|
|---|
| 133 | \section1 Example Code
|
|---|
| 134 |
|
|---|
| 135 | To illustrate how the Interview classes are used, we present two
|
|---|
| 136 | examples that show different aspects of the model/view architecture.
|
|---|
| 137 |
|
|---|
| 138 | \section2 Sharing a Model Between Views
|
|---|
| 139 |
|
|---|
| 140 | In this example, we display the contents of a model using two
|
|---|
| 141 | different views, and share the user's selection between
|
|---|
| 142 | them. We will use the QFileSystemModel supplied with Qt because it
|
|---|
| 143 | requires very little configuration, and provides existing data to
|
|---|
| 144 | the views.
|
|---|
| 145 |
|
|---|
| 146 | The main() function for this example demonstrates all the
|
|---|
| 147 | principles involved in setting up a model and two views. We also
|
|---|
| 148 | share the selection between the two views:
|
|---|
| 149 |
|
|---|
| 150 | \snippet doc/src/snippets/shareddirmodel/main.cpp 1
|
|---|
| 151 |
|
|---|
| 152 | In the above function, we construct a directory model to display
|
|---|
| 153 | the contents of a default directory. The two views are constructed
|
|---|
| 154 | and given the same model to work with. By default, each view will
|
|---|
| 155 | maintain and display its own selection of items from the model,
|
|---|
| 156 | so we explicitly create a new selection that is shared between the
|
|---|
| 157 | tree view and the list view. As a result, changes to the selection
|
|---|
| 158 | in either of these views will automatically cause the selection in
|
|---|
| 159 | the other to change.
|
|---|
| 160 |
|
|---|
| 161 | \image interview-shareddirmodel.png
|
|---|
| 162 |
|
|---|
| 163 | The model/view architecture allows us to replace the QFileSystemModel in
|
|---|
| 164 | this example with a completely different model, one that will perhaps
|
|---|
| 165 | obtain data from a remote server, or from a database.
|
|---|
| 166 |
|
|---|
| 167 | \section2 Creating a Custom Model
|
|---|
| 168 |
|
|---|
| 169 | In this example, we display items of data obtained from a custom list
|
|---|
| 170 | model using a standard view. The custom model is a subclass of
|
|---|
| 171 | QAbstractListModel and provides implementations of a core set of
|
|---|
| 172 | functions.
|
|---|
| 173 |
|
|---|
| 174 | The complete declaration of our model is as follows:
|
|---|
| 175 |
|
|---|
| 176 | \snippet doc/src/snippets/stringlistmodel/model.h 0
|
|---|
| 177 | \snippet doc/src/snippets/stringlistmodel/model.h 1
|
|---|
| 178 | \codeline
|
|---|
| 179 | \snippet doc/src/snippets/stringlistmodel/model.h 5
|
|---|
| 180 |
|
|---|
| 181 | The model takes a list of strings when constructed, and supplies these
|
|---|
| 182 | to views as required. Since this is only a simple read-only model, we
|
|---|
| 183 | only need to implement a few functions.
|
|---|
| 184 |
|
|---|
| 185 | The underlying data structure used to hold the strings is a QStringList.
|
|---|
| 186 | Since the model maps each item in the list to a row in the model, the
|
|---|
| 187 | rowCount() function is quite simple:
|
|---|
| 188 |
|
|---|
| 189 | \snippet doc/src/snippets/stringlistmodel/model.cpp 0
|
|---|
| 190 |
|
|---|
| 191 | The data() function returns an item of data for each model index
|
|---|
| 192 | supplied by a view:
|
|---|
| 193 |
|
|---|
| 194 | \snippet doc/src/snippets/stringlistmodel/model.cpp 1
|
|---|
| 195 |
|
|---|
| 196 | The data() function returns a QVariant containing the information
|
|---|
| 197 | referred to by the model index. Items of data are returned to the view,
|
|---|
| 198 | but only if a number of checks are satisfied; for example, if the view
|
|---|
| 199 | specifies an invalid model index, the model indicates this by returning
|
|---|
| 200 | an invalid QVariant.
|
|---|
| 201 |
|
|---|
| 202 | Vertical and horizontal headers are supplied by the headerData()
|
|---|
| 203 | function. In this model, the value returned for these items is the row
|
|---|
| 204 | or column number, depending on the header:
|
|---|
| 205 |
|
|---|
| 206 | \snippet doc/src/snippets/stringlistmodel/model.cpp 2
|
|---|
| 207 |
|
|---|
| 208 | We only include an excerpt from the main() function for this short
|
|---|
| 209 | example:
|
|---|
| 210 |
|
|---|
| 211 | \snippet doc/src/snippets/stringlistmodel/main.cpp 1
|
|---|
| 212 | \dots
|
|---|
| 213 | \snippet doc/src/snippets/stringlistmodel/main.cpp 3
|
|---|
| 214 |
|
|---|
| 215 | We create a string list to use with the model, and we supply it to the
|
|---|
| 216 | model when it is constructed. The information in the string list is
|
|---|
| 217 | made available to the view via the model.
|
|---|
| 218 |
|
|---|
| 219 | \image stringlistmodel.png
|
|---|
| 220 |
|
|---|
| 221 | This example shows that it can be easy to populate views with data
|
|---|
| 222 | from a simple model. The standard models and views planned for
|
|---|
| 223 | Qt 4 will make the process even easier, and the convenience widgets
|
|---|
| 224 | supplied provide support for the classic item-based approach.
|
|---|
| 225 |
|
|---|
| 226 | \section1 What's Changed Since Qt 3?
|
|---|
| 227 |
|
|---|
| 228 | The table and item view classes in Qt 3 implemented widgets that
|
|---|
| 229 | both stored data and presented it to the user. These classes were
|
|---|
| 230 | designed to be easy-to-use and consistent, but were sometimes
|
|---|
| 231 | difficult to customize and extend.
|
|---|
| 232 |
|
|---|
| 233 | The equivalent classes in Qt 4 are designed to be extensible while
|
|---|
| 234 | remaining easy-to-use; the introduction of the model/view
|
|---|
| 235 | architecture ensures that they will be more consistent than their
|
|---|
| 236 | predecessors. The view classes provided can be summarized in the
|
|---|
| 237 | following way:
|
|---|
| 238 |
|
|---|
| 239 | \list
|
|---|
| 240 | \i QListView class provides a view widget that looks similar to
|
|---|
| 241 | Qt 3's QListBox widget, but displays data provided by a model.
|
|---|
| 242 | It can also be used to display icons in a similar way to Qt 3's
|
|---|
| 243 | QIconView.
|
|---|
| 244 | \i The QTableView class is a view widget that displays tabular data
|
|---|
| 245 | like Qt 3's QTable widget, but uses data provided by a model.
|
|---|
| 246 | \i The QTreeView class provides a view widget that behaves like
|
|---|
| 247 | Qt 3's QListView widget, except that it displays data provided
|
|---|
| 248 | by a model.
|
|---|
| 249 | \endlist
|
|---|
| 250 |
|
|---|
| 251 | Since the model takes responsibility for supplying items of data,
|
|---|
| 252 | and the view takes care of their presentation to the user, we do
|
|---|
| 253 | not require item classes to represent individual items.
|
|---|
| 254 | Delegates handle the painting and editing of data obtained from
|
|---|
| 255 | the model.
|
|---|
| 256 |
|
|---|
| 257 | Qt continues to provide a number of classic item view widgets with
|
|---|
| 258 | familiar item-based interfaces that are not based on compatibility
|
|---|
| 259 | classes:
|
|---|
| 260 |
|
|---|
| 261 | \list
|
|---|
| 262 | \i The QListWidget class provides a widget to display a
|
|---|
| 263 | list of items, as found in Qt 3's QListBox class.
|
|---|
| 264 | \i The QTreeWidget class implements the equivalent of Qt 3's
|
|---|
| 265 | QListView class.
|
|---|
| 266 | \i The QTableWidget class provides comparable functionality to
|
|---|
| 267 | Qt 3's QTable class.
|
|---|
| 268 | \endlist
|
|---|
| 269 |
|
|---|
| 270 | Each of the convenience classes have a corresponding item class:
|
|---|
| 271 | QListWidgetItem, QTreeWidgetItem, and QTableWidgetItem are the Qt 4
|
|---|
| 272 | equivalents of Qt 3's QListBoxItem, QListViewItem, and QTableItem
|
|---|
| 273 | respectively.
|
|---|
| 274 |
|
|---|
| 275 | The move towards a model/view architecture presents both challenges
|
|---|
| 276 | and opportunities for developers. Although the approach may appear to
|
|---|
| 277 | be rather powerful for simple applications, it encourages greater
|
|---|
| 278 | reuse of components within applications.
|
|---|
| 279 | */
|
|---|