Models

For interacting with lists in Qt applications, you usually want to use Qt's ListView classes, which are based on the Model-View-Controller pattern. QtIvi offers support classes, making it easy to provide your own models.

The QIviAbstractFeatureListModel

When designing features like a contacts list of a connected mobile phone, you may want to use QtIvi's frontend/backend separation by deriving from QIviAbstractFeature and at the same time make it possible to use this feature with a QAbstractItemView derived class to show your contacts in a list form.

QtIviCore provides QIviAbstractFeatureListModel for this use-case. The class is derived from QAbstractListModel, but also provides all the functionality from QIviAbstractFeature.

The QIviPagingModel

The QIviPagingModel is a simple list model which uses the so-called "Pagination" concept known from the web-world to load its content from the backend when it's really needed. The model provides multiple different modes when and how the data should be retrieved and how many items should be fetched in every stage.

Fetch Modes

As we don't have control over the interfaces of the data providers, the QIviPagingModel supports two distinct fetch modes:

  1. If the number of items in the model is not known from the beginning, the FetchMore mode should be used. This mode will fetch a number of items from the backend once they are needed and the backend tells the frontend whether there is more data to be fetched.
  2. The second fetch mode - DataChanged - will fill the complete model with empty data and use the QAbstractItemModel::dataChanged() signal to tell the View about the actual content. For this mode to work correctly, the number of items in the list needs to be known from the beginning.

See the QIviPagingModel documentation for a more detailed description of the fetch modes and their (dis)advantages.

Model Data

QIviPagingModel provides a classic item-based approach to working with the model. The items in a QIviPagingModel are provided by QIviStandardItem or classes derived from it. The best way to provide the data to the QIviPagingModel is to create a new class derived from QIviStandardItem and override the "name" and "type" accessor functions. The "name" and "type" properties of every QIviStandardItem can be retrieved directly from the data() function of the model. This also exposes those properties to delegates in item views (e.g. ListView). In addition the ItemRole provides a const pointer to the stored QIviStandardItem. Using the MetaObject-System all the properties of the derived type are also available in QML directly using this pointer. From C++ the at() template function can be used to cast it directly to the needed type.

The QIviSearchAndBrowseModel

The QIviSearchAndBrowseModel is derived from the QIviPagingModel and extends its functionality. As the name suggests, it provides a model, that supports searching the model content as well as browsing through a set of model data. Let's go through all of its features in more detail:

For filtering and sorting, QIviSearchAndBrowseModel uses the Qt IVI Query Language. This makes the system very flexible and powerful at the same time. See the next page for more information about the query language.

Browsing

Although the Qt IVI Query Language supports very complex queries, enabling you to filter list content, it might still not be suitable for all use-cases. With the query language, the frontend developer defines which data is needed next. This is sometimes not possible, as the backend already defines a specific browsing order. A DLNA backend for example already specifies that first an artist needs to be selected and only then a list of all albums of that artist is presented.

For this scenario, the QIviSearchAndBrowseModel provides some methods to navigate through the models using the following methods:

Capabilities

You might not need all of the above features at the same time or your backend doesn't even support them. In this case, there is a capability system within the QIviSearchAndBrowseModel. The backend reports which capabilities it can support. Based on that information, only the supported functionalities are enabled in the frontend API.

Modifying the Content

QIviSearchAndBrowseModel provides some generic methods for modifying the content of the model:

Models as properties of a QtIvi Feature

In a lot of cases you might need a model as a property of a specific QtIvi Feature. A good example is a MediaPlayer feature, where you provide the basic player functionality like the play-state. In addition you also want to provide the current play queue as a model to display it nicely inside a ListView. As the play queue might be pretty long, a vector or list is not a suitable container for it and it makes sense to use the QIviPagingModel to only load the items actually needed.

As the QIviPagingModel is a also a QtIvi Feature, it has its own backend interface which needs to be implemented by the backend plugin.

Every model property needs to map to an unique model interface implementation in the backend, as every model is filled with different data and the data is requested at a different time and they all need to maintain their own state.

To implement this concept the QIviProxyServiceObject are used to connect the provided instance of the QIviPagingModel with the correct instance of the backend interface.

For the mediaplayer play queue example this would work as follows:

  1. On Backend side
    1. Implements the QIviPagingModelInterface to retrieve the playqueue items
    2. Implements the MediaPlayer feature interface and returns an pointer to the QIviPagingModelInterface implementation for the playqueue property
  2. On Frontend side
    1. Retrieves the QIviPagingModelInterface pointer from the backend
    2. Creates a QIviProxyServiceObject which holds the QIviPagingModelInterface
    3. Creates a QIviPagingModel instance and sets the QIviProxyServiceObject on it
    4. Returns the QIviPagingModel instance to the user

All these steps are already implemented in the ivigenerator by using the model type for a property in an interface.

© 2020 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.