c++qtqmlqabstractitemmodelqabstractlistmodel

Should I use many roles or a single one deferring the actual properties to a QObject wrapping/exposing the data as its properties


Is an QAbstractListModel implementation with say roles

name, image, enabled, color, editable

Better than an implementation with a single role (forgive me for not being able to come up with a better name)

thing

which causes a QObject* with aforementioned Q_PROPERTYs to be returned?

The difference on QML side would be an extra "indirection" when accessing the values in say, a delegate:

model.thing.name

vs

model.name

I lean towards the QObject approach, because it disentangles the data view from the list model, and has a potential for reuse. It also doesn't require you to also implement the setData function. As far as I can tell, there are no specific pro's for the "many roles" option, unless of course it's impossible to properly define a proper QObject subclass wrapping the data (because e.g. it could make little sense conceptuallyfor specific cases).


Solution

  • Having roles in a model is helpful when you want to use it with features that rely on roles.

    For example you want to feed your model to a ComboBox, if it has roles you can just specify a textRole to the ComboBox and it will do its thing. If using a single object role, you will have to modify the delegate to display your correct object property. Roles are also needed if you want to make use of ListView's section feature.

    Like @derm said, it's also useful with a QSortFilterProxyModel (shameless plug: if your model has roles, it's super easy to filter or sort it with my SortFilterProxyModel library).

    You mention reusability and having to reimplement stuff. That's a good point but it's totally doable to have a generic model with roles based on QObject properties. In fact it has been done and it is available with a very permissible license here : Thomas Boutroue's QQmlObjectListModel. From c++ it has the same API as a QList but it exposes a QAbstractListModel that is usable by QML. The roles are based on the properties of your objects, and when a notify signal is emitted, it emits the corresponding dataChanged signal. insertRows and friends are also handled automatically.

    With that said, I don't see much point in doing a model with a single object role. If you want a proper model with rowsInserted/rowRemoved signals (and you should, unless you just have a static model, in this case a QVariantList or a QObjectList is enough), you'd have to implement it yourself anyway when you can just use QQmlObjectListModel and be done with it.