1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
7 \startpage {index.html}{Qt Reference Documentation}
9 \title Model/View Tutorial
10 \brief An introduction to ModelView programming
12 Every UI developer should know about ModelView programming and the goal of
13 this tutorial is to provide you with an easily understandable introduction
16 Table, list and tree widgets are components frequently used in GUIs. There
17 are 2 different ways how these widgets can access their data. The
18 traditional way involves widgets which include internal containers for
19 storing data. This approach is very intuitive, however, in many non-trivial
20 applications, it leads to data synchronization issues.
21 The second approach is model/view programming, in
22 which widgets do not maintain internal data containers. They access external
23 data through a standardized interface and therefore avoid data duplication.
24 This may seem complicated at first, but once you take a closer look, it is
25 not only easy to grasp, but the many benefits of model/view programming also
30 In the process, we will learn about some basic technologies provided by Qt,
34 \li The difference between standard and model/view widgets
35 \li Adapters between forms and models
36 \li Developing a simple model/view application
38 \li Intermediate topics such as:
43 \li Debugging with model test
47 You will also learn whether your new application can be written easier with
48 model/view programming or if classic widgets will work just as well.
50 This tutorial includes example code for you to edit and integrate into your
51 project. The tutorial's source code is located in Qt's
52 \e examples/widgets/tutorials/modelview directory.
54 For more detailed information you may also want to look at the
55 \l{model-view-programming.html}{reference documentation}
58 \section1 1. Introduction
60 Model/View is a technology used to separate data from views in widgets that
61 handle data sets. Standard widgets are not designed for separating data
62 from views and this is why Qt has two different types of widgets. Both
63 types of widgets look the same, but they interact with data differently.
67 \li Standard widgets use data that is part of the widget.
68 \li \image standardwidget.png
70 \li View classes operate on external data (the model)
71 \li \image modelview.png
74 \section2 1.1 Standard Widgets
76 Let's have a closer look at a standard table widget. A table widget is a 2D
77 array of the data elements that the user can change. The table widget can be
78 integrated into a program flow by reading and writing the data elements that
79 the table widget provides.
80 This method is very intuitive and useful in many applications, but displaying
81 and editing a database table with a standard table widget can be problematic.
82 Two copies of the data have to be coordinated: one outside the
83 widget; one inside the widget. The developer is responsible for
84 synchronizing both versions. Besides this, the tight coupling of presentation and data
85 makes it harder to write unit tests.
87 \section2 1.2 Model/View to the Rescue
89 Model/view stepped up to provide a solution that uses a more versatile
90 architecture. Model/view eliminates the data consistency problems that may
91 occur with standard widgets. Model/view also makes it easier to use more
92 than one view of the same data because one model can be passed on to many
93 views. The most important difference is that model/view widgets do not store
94 data behind the table cells. In fact, they operate directly from your data.
95 Since view classes do not know your data's structure, you need to provide a
96 wrapper to make your data conform to the QAbstractItemModel interface. A
97 view uses this interface to read from and write to your data. Any instance
98 of a class that implements QAbstractItemModel is said to be a model. Once
99 the view receives a pointer to a model, it will read and display its content
102 \section2 1.3 Overview of the Model/View Widgets
104 Here is an overview of the model/view widgets and their corresponding
110 \li Standard Widget\br
111 (an item based convenience class)
112 \li Model/View View Class\br
113 (for use with external data)
115 \li \inlineimage listview.png
119 \li \inlineimage tableview.png
123 \li \inlineimage treeview.png
127 \li \inlineimage columnview.png
129 \li \l QColumnView shows a tree as a hierarchy of lists
131 \li \inlineimage modelview-combobox.png
132 \li {2, 1} \l QComboBox can work as both a view class and also
133 as a traditional widget
136 \section2 1.4 Using Adapters between Forms and Models
138 Having adapters between forms and models can come in handy.
140 We can edit data stored in tables directly from within the table itself, but
141 it's much more comfortable to edit data in text fields. There is no direct
142 model/view counterpart that separates data and views for widgets that
143 operate on one value (QLineEdit, QCheckBox ...) instead of a dataset, so we
144 need an adapter in order to connect the form to the source of data.
146 \l QDataWidgetMapper is a great solution because it maps form widgets to a
147 table row and makes it very easy to build forms for database tables.
149 \image widgetmapper.png
151 Another example of an adapter is \l QCompleter. Qt has \l QCompleter for
152 providing auto-completions in Qt widgets such as \l QComboBox and, as shown
153 below, \l QLineEdit. \l QCompleter uses a model as its data source.
155 \image qcompleter.png
158 \section1 2. A Simple Model/View Application
159 If you want to develop a model/view application, where should you start?
160 We recommend starting with a simple example and extending it step-by-step.
161 This makes understanding the architecture a lot easier. Trying to understand
162 the model/view architecture in detail before invoking the IDE has proven
163 to be less convenient for many developers. It is substantially easier to
164 start with a simple model/view application that has demo data. Give it a
165 try! Simply replace the data in the examples below with your own.
167 Below are 7 very simple and independent applications that show different
168 sides of model/view programming. The source code can be found inside the
169 \c{examples/widgets/tutorials/modelview} directory.
171 \section2 2.1 A Read Only Table
173 We start with an application that uses a QTableView to show data. We will
174 add editing capabilities later.
176 (file source: examples/widgets/tutorials/modelview/1_readonly/main.cpp)
177 \snippet tutorials/modelview/1_readonly/main.cpp Quoting ModelView Tutorial
179 We have the usual \l {modelview-part2-main-cpp.html}{main()} function:
181 Here is the interesting part: We create an instance of MyModel and use
182 \l{QTableView::setModel()}{tableView.setModel(&myModel);} to pass a
183 pointer of it to \l{QTableView}{tableView}. \l{QTableView}{tableView}
184 will invoke the methods of the pointer it has received to find out two
188 \li How many rows and columns should be displayed.
189 \li What content should be printed into each cell.
192 The model needs some code to respond to this.
194 We have a table data set, so let's start with QAbstractTableModel since it
195 is easier to use than the more general QAbstractItemModel.
197 (file source: examples/widgets/tutorials/modelview/1_readonly/mymodel.h)
198 \snippet tutorials/modelview/1_readonly/mymodel.h Quoting ModelView Tutorial
200 QAbstractTableModel requires the implementation of three abstract methods.
202 (file source: examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp)
203 \snippet tutorials/modelview/1_readonly/mymodel.cpp Quoting ModelView Tutorial
205 The number of rows and columns is provided by
206 \l{QAbstractItemModel::rowCount()}{MyModel::rowCount()} and
207 \l{QAbstractItemModel::columnCount()}{MyModel::columnCount()}. When the view
208 has to know what the cell's text is, it calls the method
209 \l{QAbstractItemModel::data()}{MyModel::data()}. Row and column information
210 is specified with parameter \c index and the role is set to
211 \l{Qt::ItemDataRole}{Qt::DisplayRole}. Other roles are covered in the next
212 section. In our example, the data that should be displayed is generated. In
213 a real application, \c MyModel would have a member called \c MyData, which
214 serves as the target for all reading and writing operations.
216 This small example demonstrates the passive nature of a model. The model
217 does not know when it will be used or which data is needed. It simply
218 provides data each time the view requests it.
220 What happens when the model's data needs to be changed? How does the view
221 realize that data has changed and needs to be read again? The model has to
222 emit a signal that indicates what range of cells has changed. This will be
223 demonstrated in section 2.3.
225 \section2 2.2 Extending the Read Only Example with Roles
227 In addition to controlling what text the view displays, the model also
228 controls the text's appearance. When we slightly change the model, we get
229 the following result: \image readonlytable_role.png
231 In fact, nothing except for the \l{QAbstractItemModel::}{data()} method
232 needs to be changed to set fonts, background colour, alignment and a
234 Below is the \l{QAbstractItemModel::data()}{data()} method that produces the
235 result shown above. The difference is that this time we use parameter int
236 role to return different pieces of information depending on its value.
238 (file source: examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp)
239 \snippet tutorials/modelview/2_formatting/mymodel.cpp Quoting ModelView Tutorial
241 Each formatting property will be requested from the model with a separate
242 call to the \l{QAbstractItemModel::data()}{data()} method. The \c role
243 parameter is used to let the model know which property is being requested:
247 \li \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
251 \li \l{Qt::ItemDataRole}{}Qt::DisplayRole
255 \li \l{Qt::ItemDataRole}{Qt::FontRole}
259 \li \l{Qt::ItemDataRole}{BackgroundRole}
260 \li brush for the background of the cell
263 \li \l{Qt::ItemDataRole}{Qt::TextAlignmentRole}
265 \li \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag}
267 \li {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole}
268 \li {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()},
270 sets checkboxes with \l{Qt::CheckState}{Qt::Checked}
272 or \l{Qt::CheckState}{Qt::Unchecked}
273 \li {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
276 Refer to the Qt namespace documentation to learn more about the
277 \l{Qt::ItemDataRole}{Qt::ItemDataRole} enum's capabilities.
279 Now we need to determine how using a separated model impacts the
280 application's performance, so let's trace how often the view calls the
281 \l{QAbstractItemModel::}{data()} method. In order to track how often the
282 view calls the model, we have put a debug statement in the
283 \l{QAbstractItemModel::}{data()} method, which logs onto the error output
284 stream. In our small example, \l{QAbstractItemModel::}{data()} will be
286 Each time you hover the cursor over the field,
287 \l{QAbstractItemModel::}{data()} will be called again -- 7 times for
288 each cell. That's why it is important to make sure that your data is
289 available when \l{QAbstractItemModel::}{data()} is invoked and expensive
290 lookup operations are cached.
292 \section2 2.3 A Clock inside a Table Cell
296 We still have a read only table, but this time the content changes every
297 second because we are showing the current time.
299 (file source: examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
300 \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_QVariant
302 Something is missing to make the clock tick. We need to tell the view every
303 second that the time has changed and that it needs to be read again. We do
304 this with a timer. In the constructor, we set its interval to 1 second and
305 connect its timeout signal.
307 (file source: examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
308 \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_a
310 Here is the corresponding slot:
312 (file source: examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
313 \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_b
315 We ask the view to read the data in the top left cell again by emitting the
316 \l{QAbstractItemModel::}{dataChanged()} signal. Note that we did not
317 explicitly connect the \l{QAbstractItemModel::}{dataChanged()} signal to the
318 view. This happened automatically when we called \l{QTableView::}{setModel()}.
320 \section2 2.4 Setting up Headers for Columns and Rows
322 Headers can be hidden via a view method: \c{tableView->verticalHeader()->hide();}
323 \image modelview-header.png
325 The header content, however, is set via the model, so we reimplement the
326 \l{QAbstractItemModel::headerData()}{headerData()} method:
328 (file source: examples/widgets/tutorials/modelview/4_headers/mymodel.cpp)
329 \snippet tutorials/modelview/4_headers/mymodel.cpp quoting mymodel_c
331 Note that method \l{QAbstractItemModel::headerData()}{headerData()} also has
332 a parameter role which has the same meaning as in
333 \l{QAbstractItemModel::data()}{MyModel::data()}.
335 \section2 2.5 The Minimal Editing Example
337 In this example, we are going to build an application that automatically
338 populates a window title with content by repeating values entered into table
339 cells. To be able to access the window title easily we put the QTableView in
342 The model decides whether editing capabilities are available. We only have
343 to modify the model in order for the available editing capabilities to be
344 enabled. This is done by reimplementing the following virtual methods:
345 \l{QAbstractItemModel::}{setData()} and \l{QAbstractItemModel::}{flags()}.
347 (file source: examples/widgets/tutorials/modelview/5_edit/mymodel.h)
348 \snippet tutorials/modelview/5_edit/mymodel.h Quoting ModelView Tutorial
350 We use \c the two-dimensional array QString \c m_gridData to store our data.
351 This makes \c m_gridData the core of \c MyModel. The rest of \c MyModel acts
352 like a wrapper and adapts \c m_gridData to the QAbstractItemModel
353 interface. We have also introduced the \c editCompleted() signal, which
354 makes it possible to transfer the modified text to the window title.
356 (file source: examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
357 \snippet tutorials/modelview/5_edit/mymodel.cpp quoting mymodel_e
359 \l{QAbstractItemModel::setData()}{setData()} will be called each time the
360 user edits a cell. The \c index parameter tells us which field has been
361 edited and \c value provides the result of the editing process. The role
362 will always be set to \l Qt::EditRole because our cells only contain text.
363 If a checkbox were present and user permissions are set to allow the
364 checkbox to be selected, calls would also be made with the role set to
365 \l Qt::CheckStateRole.
367 (file source: examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
368 \snippet tutorials/modelview/5_edit/mymodel.cpp quoting mymodel_f
370 Various properties of a cell can be adjusted with
371 \l{QAbstractItemModel::flags()}{flags()}.
373 Returning \l{Qt::ItemFlag}{Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled}
374 is enough to show an editor that a cell can be selected.
376 If editing one cell modifies more data than the data in that particular
377 cell, the model must emit a \l{QAbstractItemModel::}{dataChanged()} signal
378 in order for the data that has been changed to be read.
381 \section1 3. Intermediate Topics
383 \section2 3.1 TreeView
385 You can convert the example above into an application with a tree view.
386 Simply replace QTableView with QTreeView, which results in a read/write
387 tree. No changes have to be made to the model. The tree won't have any
388 hierarchies because there aren't any hierarchies in the model itself.
390 \image dummy_tree.png
392 QListView, QTableView and QTreeView all use a model abstraction, which is a
393 merged list, table and tree. This makes it possible to use several different
394 types of view classes from the same model.
396 \image list_table_tree.png
398 This is how our example model looks so far:
400 \image example_model.png
402 We want to present a real tree. We have wrapped our data in the examples
403 above in order to make a model. This time we use QStandardItemModel, which
404 is a container for hierarchical data that also implements
405 QAbstractItemModel. To show a tree, QStandardItemModel must be populated
406 with \l{QStandardItem}s, which are able to hold all the standard properties
407 of items like text, fonts, checkboxes or brushes.
409 \image tree_2_with_algorithm.png
411 (file source: examples/widgets/tutorials/modelview/6_treeview/mainwindow.cpp)
412 \snippet tutorials/modelview/6_treeview/mainwindow.cpp Quoting ModelView Tutorial
414 We simply instantiate a QStandardItemModel and add a couple of
415 \l{QStandardItem}{QStandardItems} to the constructor. We can then make a
416 hierarchical data structure because a QStandardItem can hold other
417 \l{QStandardItem}{QStandardItems}. Nodes are collapsed and expanded within
420 \section2 3.2 Working with Selections
422 We want to access a selected item's content in order to output it into the
423 window title together with the hierarchy level.
425 \image selection2.png
427 So let's create a couple of items:
429 (file source: examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp)
430 \snippet tutorials/modelview/7_selections/mainwindow.cpp quoting modelview_a
432 Views manage selections within a separate selection model, which can be
433 retrieved with the \l{QAbstractItemView::}{selectionModel()} method. We
434 retrieve the selection Model in order to connect a slot to its
435 \l{QAbstractItemView::}{selectionChanged()} signal.
437 (file source: examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp)
438 \snippet tutorials/modelview/7_selections/mainwindow.cpp quoting modelview_b
440 We get the model index that corresponds to the selection by calling
441 \l{QItemSelectionModel::currentIndex()}{treeView->selectionModel()->currentIndex()}
442 and we get the field's string by using the model index. Then we just
443 calculate the item's \c hierarchyLevel. Top level items do not have parents
444 and the \l{QAbstractItemModel::}{parent()} method will return a default
445 constructed \l{QModelIndex}{QModelIndex()}. This is why we use the
446 \l{QAbstractItemModel::}{parent()} method to iterate to the top level while
447 counting the steps performed during iteration.
449 The selection model (as shown above) can be retrieved, but it can also be
450 set with \l{QAbstractItemView}{QAbstractItemView::setSelectionModel}. This
451 is how it's possible to have 3 view classes with synchronized selections
452 because only one instance of a selection model is used. To share a selection
453 model between 3 views use \l{QAbstractItemView::}{selectionModel()} and
454 assign the result to the second and third view class with
455 \l{QAbstractItemView::}{setSelectionModel()}.
457 \section2 3.3 Predefined Models
459 The typical way to use model/view is to wrap specific data to make it usable
460 with view classes. Qt, however, also provides predefined models for common
461 underlying data structures. If one of the available data structures is
462 suitable for your application, a predefined model can be a good choice.
467 \li Stores a list of strings
469 \li QStandardItemModel
470 \li Stores arbitrary hierarchical items
473 \li Encapsulate the local file system
476 \li Encapsulate an SQL result set
479 \li Encapsulates an SQL table
481 \li QSqlRelationalTableModel
482 \li Encapsulates an SQL table with foreign keys
484 \li QSortFilterProxyModel
485 \li Sorts and/or filters another model
489 \section2 3.4 Delegates
491 In all examples so far, data is presented as text or a checkbox in a cell
492 and is edited as text or a checkbox. The component that provides these
493 presentation and editing services is called a \e delegate. We are only just
494 beginning to work with the delegate because the view uses a default
495 delegate. But imagine that we want to have a different editor (e.g., a
496 slider or a drop down list) Or imagine that we want to present data as
498 Let's take a look at an example called \l{Star Delegate Example}{Star
499 Delegate}, in which stars are used to show a rating:
501 \image stardelegate.png
503 The view has a \l{QAbstractItemView::}{setItemDelegate()} method that
504 replaces the default delegate and installs a custom delegate.
505 A new delegate can be written by creating a class that inherits from
506 QStyledItemDelegate. In order to write a delegate that displays stars and
507 has no input capabilities, we only need to override 2 methods.
510 class StarDelegate : public QStyledItemDelegate
514 StarDelegate(QWidget *parent = nullptr);
515 void paint(QPainter *painter, const QStyleOptionViewItem &option,
516 const QModelIndex &index) const;
517 QSize sizeHint(const QStyleOptionViewItem &option,
518 const QModelIndex &index) const;
522 \l{QStyledItemDelegate::}{paint()} draws stars depending on the content of
523 the underlying data. The data can be looked up by calling
524 \l{QModelIndex::data()}{index.data()}. The delegate's
525 \l{QAbstractItemDelegate::}{sizeHint()} method is used to obtain each
526 star's dimensions, so the cell will provide enough height and width to
527 accommodate the stars.
529 Writing custom delegates is the right choice if you want to show your data
530 with a custom graphical representation inside the grid of the view class. If
531 you want to leave the grid, you would not use a custom delegate but a custom
534 Other references to delegates in Qt Documentation:
537 \li \l{Spin Box Delegate Example}
538 \li \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
539 \li \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
540 \li \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
541 \li \l{QItemDelegate}{QItemDelegate Class Reference}
545 \section2 3.5 Debugging with ModelTest
547 The passive nature of models provides new challenges for programmers.
548 Inconsistencies in the model can cause the application to crash. Since the
549 model is hit by numerous calls from the view, it is hard to find out which
550 call has crashed the application and which operation has introduced the
553 Qt Labs provides software called
554 \l{http://wiki.qt.io/Model_Test}{ModelTest},
555 which checks models while your programming is running. Every time the model
556 is changed, ModelTest scans the model and reports errors with an assert.
557 This is especially important for tree models, since their hierarchical
558 nature leaves many possibilities for subtle inconsistencies.
560 Unlike view classes, ModelTest uses out of range indexes to test the model.
561 This means your application may crash with ModelTest even if it runs
562 perfectly without it. So you also need to handle all of the indexes that are
563 out of range when using ModelTest.
566 \section1 4. Good Sources of Additional Information
570 Model/View programming is covered quite extensively in the documentation of
571 Qt but also in several good books.
574 \li \b{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield,
575 \e{Prentice Hall, 2nd edition}, ISBN 0-13-235416-0. Also available in
576 German: \b{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung},
577 \e{Addison-Wesley}, ISBN 3-827327-29-6
578 \li \b{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin,
579 \e{Open Source Press}, ISBN 1-59327-147-6.
580 Translated from \b{Qt 4, Einführung in die Applikationsentwicklung},
581 \e{Open Source Press}, ISBN 3-937514-12-0.
582 \li \b{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8.
583 \li \b{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6.
584 This book covers Model/View programming on more than 150 pages.
587 The following list provides an overview of example programs contained in the first three
588 books listed above. Some of them make very good templates for developing similar
603 \li Book 1, Chapter 10, Figure 10.6
607 \li QSortFilterProxyModel
608 applied to QStringListModel
610 \li Book 1, Chapter 10, Figure 10.8
614 \li custom model based on
617 \li Book 1, Chapter 10, Figure 10.10
621 \li Custom model based on
624 \li Book 1, Chapter 10, Figure 10.12
628 \li Custom model based on
631 \li Book 1, Chapter 10, Figure 10.14
634 \li {2, 1} QTableWidget
635 \li Custom delegate providing a custom editor
636 \li Book 1, Chapter 10, Figure 10.15
643 \li Custom model based on
646 \li Book2, Chapter 8.4
648 \li Address Book with sorting
650 \li QSortfilterProxyModel
651 \li Introducing sort and filter capabilities
652 \li Book2, Chapter 8.5
658 \li Introducing checkboxes in model/view
659 \li Book2, Chapter 8.6
661 \li Address Book with transposed grid
663 \li Custom proxy Model based on QAbstractProxyModel
664 \li Introducing a custom model
665 \li Book2, Chapter 8.7
667 \li Address Book with drag and drop
670 \li Introducing drag and drop support
671 \li Book2, Chapter 8.8
673 \li Address Book with custom editor
676 \li Introducing custom delegates
677 \li Book2, Chapter 8.9
683 \li QStandardItemModel
685 \li Book 3, Chapter 5, figure 5-3
690 \li Custom delegate for presentation based on QAbstractItemDelegate
691 \li Book 3, Chapter 5, figure 5-5
696 \li Custom delegate for editing based on QAbstractItemDelegate
697 \li Book 3, Chapter 5, figure 5-6
700 \li Custom view based on QAbstractItemView
709 \li Custom Model based on QAbstractTableModel
711 \li Book 3, Chapter 5, Figure 5-8
715 \li Custom Model based on QAbstractItemModel
717 \li Book 3, Chapter 5, Figure 5-10
721 \li Custom Model based on QAbstractListModel
723 \li Book 3, Chapter 5, Listing 5-37, Figure 5-11
727 \li QSortFilterProxyModel applied to QStringListModel
728 \li Demonstrates sorting
729 \li Book 3, Chapter 5, Figure 5-12
733 \section2 4.2 Qt Documentation
735 Qt 5.0 comes with 19 examples for model/view.
736 The examples can be found on the \l{Item Views Examples} page.
747 \li QAbstractTableModel
748 QSortFilterProxyModel
749 \li Usage of QSortFilterProxyModel to generate different
750 subsets from one data pool
752 \li Basic Sort/Filter Model
754 \li QStandardItemModel
755 QSortFilterProxyModel
760 \li QStandardItemModel
761 \li Designing custom views that cooperate with selection models
763 \li Color Editor Factory
764 \li {2, 1} QTableWidget
765 \li Enhancing the standard delegate with a new custom editor to choose colours
767 \li Combo Widget Mapper
768 \li QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox
769 \li QStandardItemModel
770 \li Shows how a QComboBox can serve as a view class
772 \li Custom Sort/Filter Model
774 \li QStandardItemModel
775 QSortFilterProxyModel
776 \li Subclass QSortFilterProxyModel for advanced sorting and filtering
781 \li Very small example to demonstrate how to assign a model to a view
783 \li Editable Tree Model
785 \li Custom tree model
786 \li Comprehensive example for working with trees, demonstrates
787 editing cells and tree structure with an underlying custom
792 \li Custom list model
793 \li Dynamically changing model
797 \li QStandardItemModel
802 \li Custom item model
807 \li Custom table model
808 \li Implementation of a custom delegate
812 \li Custom list model
813 \li Model/view with drag and drop
817 \li Custom tree model
818 \li Read only example for a custom tree model
820 \li Simple Tree Model
822 \li Custom tree model
823 \li Read only example for a custom tree model
825 \li Simple Widget Mapper
826 \li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
827 \li QStandardItemModel
828 \li Basic QDataWidgetMapper usage
830 \li Spin Box Delegate
832 \li QStandardItemModel
833 \li Custom delegate that uses a spin box as a cell editor
836 \li {2, 1} QTableView
840 \li {2, 1} QTableWidget
841 \li Comprehensive custom delegate example.
844 A \l{Model/View Programming}{reference document} for model/view technology
849 \page modelview-part2-main-cpp.html
851 \quotefile tutorials/modelview/1_readonly/main.cpp