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