Models

To interact with lists in Qt applications, typically, you would use Qt's ListView classes, which are based on the Model-View-Controller (MVC) pattern. Similarly, QtIvi has the following classes that support this use case, for you to provide your own models:

Apart from creating standalone models using one of classes mentioned above, you can also provide models that are properties of an existing feature.

QIviAbstractFeatureListModel

Suppose you have to design a feature like a Contact List in a connected Mobile Phone, you can use QtIvi's frontend/backend separation by deriving from QIviAbstractFeature. Then, you use your subclass 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.

QIviPagingModel

The QIviPagingModel is a list model that uses the well-known Pagination concept to only load content from the backend, when it is needed. This model provides two different modes that determine when and how data should be retrieved and the number of items to fetch in each stage.

Fetch Modes

Since we don't have control on the data providers' interfaces, the QIviPagingModel supports two fetch modes:

  1. If the number of items in the model is not known from the beginning, use the FetchMore mode. This mode fetches a number of items from the backend when they are needed; the backend tells the frontend whether there is more data to be fetched.
  2. If the number of items in the model is known from the beginning, use the DataChanged mode. This mode fills the complete model with empty data and then uses the QAbstractItemModel::dataChanged() signal to tell the view about the actual content.

For more details on fetch modes, see QIviPagingModel.

Model Data

QIviPagingModel provides a classic item-based approach to working with the model; the items are provided by QIviStandardItem or classes derived from it. The best way to provide data to the QIviPagingModel is to create a new class derived from QIviStandardItem. Then, override the name() and type() accessor functions. The name and type properties for each QIviStandardItem can be retrieved directly from the model's data() function. This function also exposes those properties to delegates in item views, such as ListView. In addition, the ItemRole provides a const pointer to the QIviStandardItem stored. Using The Meta-Object System, all the properties from the derived type are also available in QML, directly, with this pointer. From C++, you can use the at() template function to cast this const pointer directly to the type you need.

QIviSearchAndBrowseModel

The QIviSearchAndBrowseModel is derived from the QIviPagingModel to extends its functionality. This class provides a model that supports searching through its content and browsing through a set of model data.

Search: Filter and Sort

To filter and sort, QIviSearchAndBrowseModel uses the Qt IVI Query Language; this makes the system both flexible and powerful.

Browse

Although the Qt IVI Query Language supports very complex queries, enabling you to filter content in a list, it may not suit all use cases. With the query language, the frontend developer defines which data is needed next. Sometimes, this is not possible, if the backend already has a fixed browsing order. For example, a DLNA backend already specifies that an artist needs to be selected first, only then is a list of all albums for that artist presented.

For this scenario, the {QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel} provides some methods to navigate through the models:

Capabilities

You might not need all of the features above simultaneously; or your backend may not support all of them. In this case, the QIviSearchAndBrowseModel has a capabilities feature where the backend reports which capabilities it can support. Based on that information, only the supported functionalities are enabled in the frontend API.

Modify the Content

{QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel} provides some generic methods to modify the contents of the model:

Models as Properties of a QtIvi Feature

In some 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.

This play queue might be long, a vector or list is not a suitable container for it. Using the {QIviPagingModel::QIviPagingModel}{QIviPagingModel} to only load the items, is a logical conclusion.

As the {QIviPagingModel::QIviPagingModel}{QIviPagingModel} is a also a QtIvi Feature, it has its own backend interface which the backend plugin needs to implement.

Each model property needs to map to a unique model interface implementation in the backend, as each model is filled with different data and the data is requested at a different time. Ultimately, every model instance needs to maintain its own state.

To implement this concept, we use the QIviProxyServiceObject to connect the {QIviPagingModel::QIviPagingModel}{QIviPagingModel} instance provided with the correct backend interface instance.

For the MediaPlayer play queue example, we would implement the following:

  1. For the Backend
    1. Implement the QIviPagingModelInterface to retrieve the play queue items
    2. Implement the MediaPlayer feature interface and return a pointer to the QIviPagingModelInterface implementation for the play queue property
  2. For the Frontend
    1. Retrieve the QIviPagingModelInterface pointer from the backend
    2. Create a QIviProxyServiceObject that holds the QIviPagingModelInterface
    3. Create a QIviPagingModel instance and set the QIviProxyServiceObject on it
    4. Return the QIviPagingModel instance to the developer

All these steps are already implemented in the IVIGenerator, via 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.