Home · All Namespaces · All Classes · Main Classes · Grouped Classes · Modules · Functions

[Previous: Model/View Programming] [Next: Using Models and Views]

An Introduction to Model/View Programming

Qt 4 introduces a new set of item view classes that use a model/view architecture to manage the relationship between data and the way it is presented to the user. The separation of functionality introduced by this architecture gives developers greater flexibility to customize the presentation of items, and provides a standard model interface to allow a wide range of data sources to be used with existing item views. In this document, we give a brief introduction to the model/view paradigm, outline the concepts involved, and describe the architecture of the item view system. Each of the components in the architecture is explained, and examples are given that show how to use the classes provided.

The Model/View Architecture

Model-View-Controller (MVC) is a design pattern originating from Smalltalk that is often used when building user interfaces. In Design Patterns, Gamma et al. write:

MVC consists of three kinds of objects. The Model is the application object, the View is its screen presentation, and the Controller defines the way the user interface reacts to user input. Before MVC, user interface designs tended to lump these objects together. MVC decouples them to increase flexibility and reuse.

If the view and the controller objects are combined, the result is the model/view architecture. This still separates the way that data is stored from the way that it is presented to the user, but provides a simpler framework based on the same principles. This separation makes it possible to display the same data in several different views, and to implement new types of views, without changing the underlying data structures. To allow flexible handling of user input, we introduce the concept of the delegate. The advantage of having a delegate in this framework is that it allows the way items of data are rendered and edited to be customized.

The model/view architecture

The model communicates with a source of data, providing an interface for the other components in the architecture. The nature of the communication depends on the type of data source, and the way the model is implemented.

The view obtains model indexes from the model; these are references to items of data. By supplying model indexes to the model, the view can retrieve items of data from the data source.

In standard views, a delegate renders the items of data. When an item is edited, the delegate communicates with the model directly using model indexes.

Generally, the model/view classes can be separated into the three groups described above: models, views, and delegates. Each of these components is defined by abstract classes that provide common interfaces and, in some cases, default implementations of features. Abstract classes are meant to be subclassed in order to provide the full set of functionality expected by other components; this also allows specialized components to be written.

Models, views, and delegates communicate with each other using signals and slots:

Models

All item models are based on the QAbstractItemModel class. This class defines an interface that is used by views and delegates to access data. The data itself does not have to be stored in the model; it can be held in a data structure or repository provided by a separate class, a file, a database, or some other application component.

The basic concepts surrounding models are presented in the section on Model Classes.

QAbstractItemModel provides an interface to data that is flexible enough to handle views that represent data in the form of tables, lists, and trees. However, when implementing new models for list and table-like data structures, the QAbstractListModel and QAbstractTableModel classes are better starting points because they provide appropriate default implementations of common functions. Each of these classes can be subclassed to provide models that support specialized kinds of lists and tables.

The process of subclassing models is discussed in the section on Creating New Models.

Qt provides some ready-made models that can be used to handle items of data:

If these standard models do not meet your requirements, you can subclass QAbstractItemModel, QAbstractListModel, or QAbstractTableModel to create your own custom models.

Views

Complete implementations are provided for different kinds of views: QListView displays a list of items, QTableView displays data from a model in a table, and QTreeView shows model items of data in a hierarchical list. Each of these classes is based on the QAbstractItemView abstract base class. Although these classes are ready-to-use implementations, they can also be subclassed to provide customized views.

The available views are examined in the section on View Classes.

Delegates

QAbstractItemDelegate is the abstract base class for delegates in the model/view framework. Since Qt 4.4, the default delegate implementation is provided by QStyledItemDelegate, and this is used as the default delegate by Qt's standard views. However, QStyledItemDelegate and QItemDelegate are independent alternatives to painting and providing editors for items in views. The difference between them is that QStyledItemDelegate uses the current style to paint its items. We therefore recommend using QStyledItemDelegate as the base class when implementing custom delegates or when working with Qt style sheets.

Delegates are described in the section on Delegate Classes.

Sorting

There are two ways of approaching sorting in the model/view architecture; which approach to choose depends on your underlying model.

If your model is sortable, i.e, if it reimplements the QAbstractItemModel::sort() function, both QTableView and QTreeView provide an API that allows you to sort your model data programmatically. In addition, you can enable interactive sorting (i.e. allowing the users to sort the data by clicking the view's headers), by connecting the QHeaderView::sectionClicked() signal to the QTableView::sortByColumn() slot or the QTreeView::sortByColumn() slot, respectively.

The alternative approach, if your model do not have the required interface or if you want to use a list view to present your data, is to use a proxy model to transform the structure of your model before presenting the data in the view. This is covered in detail in the section on Proxy Models.

Convenience Classes

A number of convenience classes are derived from the standard view classes for the benefit of applications that rely on Qt's item-based item view and table classes. They are not intended to be subclassed, but simply exist to provide a familiar interface to the equivalent classes in Qt 3. Examples of such classes include QListWidget, QTreeWidget, and QTableWidget; these provide similar behavior to the QListBox, QListView, and QTable classes in Qt 3.

These classes are less flexible than the view classes, and cannot be used with arbitrary models. We recommend that you use a model/view approach to handling data in item views unless you strongly need an item-based set of classes.

If you wish to take advantage of the features provided by the model/view approach while still using an item-based interface, consider using view classes, such as QListView, QTableView, and QTreeView with QStandardItemModel.

The Model/View Components

The following sections describe the way in which the model/view pattern is used in Qt. Each section provides an example of use, and is followed by a section showing how you can create new components.

[Previous: Model/View Programming] [Next: Using Models and Views]


Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) Trademarks
Qt 4.5.1