CopperSpice API  1.9.1
Built-In View Classes

Existing Models

Two of the standard models provided in CopperSpice are QStandardItemModel and QFileSystemModel.

QStandardItemModel is a general purpose model which can be used to represent various different data structures needed by list, table, and tree views. This model also holds the items of data.

QFileSystemModel is a model that maintains information about the contents of a directory. As a result, it does not hold any items of data itself but simply represents files and directories on the local filing system.

Existing View Classes

In the Model/View architecture the view obtains items of data from the model and presents them to the user. The way that the data is presented does not need to resemble the representation of the data provided by the model, and may be completely different from the underlying data structure used to store items of data.

The separation of content and presentation is achieved by the use of a model interface provided by QAbstractItemModel, a view interface provided by QAbstractItemView, and the use of model indexes that represent items of data in a general way. Views typically manage the overall layout of the data obtained from models. They may render individual items of data themselves, or use Delegates Classes to handle both rendering and editing features.

As well as presenting data, views handle navigation between items, and some aspects of item selection. The views also implement basic user interface features, such as context menus and drag and drop. A view can provide default editing facilities for items, or it may work with a delegate to provide a custom editor.

A view can be constructed without a model, but a model must be provided before the view can display useful information. Views keep track of the items the user has selected through the use of Making Selections in a Model which can be maintained separately for each view or shared between multiple views.

Some views such as QTableView and QTreeView can display headers as well as the items. The header is implemented by a separate view class named QHeaderView. Headers usually access the same model as the view. They retrieve data from the model using the QAbstractItemModel::headerData() method and usually display header information in the form of a label. A custom header can be created by inheriting from the QHeaderView class.

Using a Predefined View

CopperSpice provides three built in view classes which present data from models in ways that are familiar to most users. QListView can display items from a model as a simple list, or in the form of a classic icon view. QTreeView displays items from a model as a hierarchy of lists, allowing deeply nested structures to be represented in a compact way. QTableView presents items from a model in the form of a table, much like the layout of a spreadsheet application.

The default behavior of the standard views shown above should be sufficient for most applications. They provide basic editing facilities and can be customized to suit the needs of more specialized user interfaces.

Rows and Columns in a Model

The data in a model is accessed by passing the row and column values to the index() method of the model.

QModelIndex index = model->index(row, column);

Models that provide interfaces to single level data structures like a list or a table do not need any other information.

The diagram shows a representation of a basic table model in which each item can be identified by a pair of row and column numbers. The top level items in a model use an empty QModelIndex() as their parent.

QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexB = model->index(1, 1, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());

Model Item Roles

Items in a model can have multiple roles, allowing different kinds of data to be supplied for different situations. For example, Qt::DisplayRole is used to access a string that can be displayed as text in a view. Typically, items contain data for a number of different roles and the standard roles are defined by Qt::ItemDataRole.

The view can query the model for information about a given item by passing the model index corresponding to the item and specifying a role.

QVariant value = model->data(index, role);

By returning the appropriate item data for each role, models can provide hints to views and delegates about how items should be presented to the user. Different kinds of views have the freedom to interpret or ignore this information as required. It is also possible to define additional roles for application specific purposes.

Using a QFileSystemModel

The QListView and QTreeView classes are the most suitable views to use with the QFileSystemModel. The example presented below displays the contents of a directory in a tree view next to the same information in a list view. The views share the user's selection so that the selected items are highlighted in both views.

A QFileSystemModel is constructed and two views are created to display the contents of a directory. The model is set to use data from the file system. The call to setRootPath() tells the model which drive on the file system to expose to the views.

The views are constructed in the same way as other widgets. Setting up a view to display the items in the model is simply a matter of calling its setModel() method with the directory model as the argument. We filter the data supplied by the model by calling the setRootIndex() method on each view, passing a suitable model index from the file system model for the current directory.

The index() method is used in this case is unique to QFileSystemModel. Passing a directory returns a model index. Model indexes are discussed in more detail in the section Model Indexes.

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QSplitter *splitter = new QSplitter;
// create model
// create view
QTreeView *tree = new QTreeView(splitter);
tree->setModel(model);
// create view
QListView *list = new QListView(splitter);
list->setModel(model);
list->setRootIndex(model->index(QDir::currentPath()));

The rest of the code displays the views within a splitter widget and runs the application event loop.

splitter->setWindowTitle("Two views of the same file system model");
splitter->show();
return app.exec();
}

More information about handling selections can be found in the section about Making Selections in a Model.