13.1. Model-View-Controller (MVC)

[ fromfile: modelview.xml id: mvc ]

Controller code manages the interactions among events, models, and views. Factory methods, delegates, and creation and destruction code in general, all fall into the realm of the Controller. In the Qt framework, much of the Controller mechanism can be found in delegates. Delegates control the rendering and editing of individual items in views. Views supply default delegates that are sufficient for most purposes, although we can, if necessary, refine the ways that the default delegates render items by deriving a custom model from QAbstractItemModel.

Data and Roles.  When you get and set data, there is an optional role parameter, that lets you specify values for particular roles from Qt::ItemDataRole, used by the view when it requires data from the model. Some roles specify general purpose data values, such as Qt::DisplayRole (the default), Qt::EditRole (the data in a QVariant suitable for editing) or Qt::ToolTipRole (the data is a QString displayed in a tooltip). Other roles can describe appearance, such as Qt::FontRole, which enables the default delegate to specify a particular QFont, or Qt::TextAlignmentRole, which enables the default delegate to specify a particular Qt::AlignmentFlag. Qt::DecorationRole is used for icons which can decorate values in a View. Typically, you would use a QColor, QIcon, or QPixmap for this role type. Values of Qt::UserRole and above can be defined for your own purposes. Think of these as extra columns of data in the table model.

A Model-View-Controller framework, illustrated in Figure 13.2, uses a number of design patterns to make it possible to write applications that provide more than one view of the same data. It specifies that model code (responsible for maintaining the data), the view code (responsible for displaying all or part of the data in various ways), and the controller code (responsible for handling events that impact both the data and the model, such as Delegates) be kept in separate classes. This separation enables views and controllers to be added or removed without requiring changes in the model. It enables multiple views to be kept up to date and consistent with the model, even if the data is being interactively edited from more than one view. It maximizes code reuse by enabling subtitution of one model for another, or one view for another.

Figure 13.2. Model-View-Controller Classes

Model-View-Controller Classes

The primary purpose of a controller class is to encapsulate controller code. A complex application might have multiple controllers for different subcomponents, or layers, of the application.

In Qt, the base class for a wide variety of controller classes is QAbstractItemDelegate. Code that connects signals to slots can also be considered controller code. As you will see, keeping controller code out of model and view classes can yield additional design benefits.