4

Whenever I was creating a Q_PROPERTY for later use in Qml I always created a notify signal to tell qml that data changed and needs to be reevaluated.

Now having a Q_PROPERTY of the type QQmlListProperty<T> how can I signalize that an item has been modified, added or removed?

Is this even possible?

feedc0de
  • 3,646
  • 8
  • 30
  • 55
  • Do you need to populate the list from QML ? – GrecKo Jul 25 '17 at 14:25
  • Yes. I will also need to add items on button click. The list could be changed from C++ or from Qml. I want it to work in both directions. – feedc0de Jul 25 '17 at 14:29
  • If it's for a model belonging in your c++ logic layer, use a `QAbstractItemModel` to expose it. It has signals for modifications, inserts or removes. – GrecKo Jul 25 '17 at 14:41
  • The property is already part of a QAbstractListModel... In the background it's just a QStringList, isnt there an easy way using QQmlListProperty? – feedc0de Jul 25 '17 at 14:45

1 Answers1

2

If you have a list there can't be a propertyChanged() signal, because the object reference stored will remain the same.
Within the list there won't be properties, so no signal is emitted.

You could instead use a descendent of QAbstractListModel which is designed to handle this problem, by wrapping the methods to append, insert etc. in own methods, that then will emit a dataChanged signal that carries the information necessary to find the changes.

Of course you could implement something similar yourself by wrapping a QList in another object, that has a signal that will inform you of the data change. However this won't integrate that nicely with QML as a real model, for at least view will update automatically, when the dataChanged signal is received, and they even only update what is necessary.

Not so, if the model of the View is changed directly, as might happen, if you manually call modelChanged(). In this case, the View would miss the information about the changed parts, so it will just recreate itself completely.

  • If I should use a model instead, then what's the purpose of a `QQmlListProperty` then? Does it only make sense if the data is modified from Qml only? – feedc0de Jul 25 '17 at 14:47
  • Or another more important question for my project: how can I remove items at all? There is only a clear and an append method defined... – feedc0de Jul 25 '17 at 14:51
  • 1
    Yes for me it only makes sense when defining a new QML type from c++ and you want it to have a list property that you populate from QML. Like Item's `states` property – GrecKo Jul 25 '17 at 15:29
  • You are right. I was in a haste yesterday, delete is not possible. As *GrecKo* already explained: The usecase is not the one of an array to alter all the time, but to allow to assign multiple objects. One example are the `states` of each `Item`. Also the `ListModel` uses as `QQmlListProperty` to store the initially declaratively assigned model entries. Compared to a `var` you can enforce certain types (`ListModel` -> `ListElement`) and it is much simpler to handle than a `QJSValue` on the C++-side. – derM - not here for BOT dreams Jul 26 '17 at 09:05
  • @derM actually I think the ListModel uses a `QQmlCustomParser` to populate a `QAbstractListModel` which means it is not possible to copy its approach :( because the custom parser is not in public API – Mark Ch Jul 27 '17 at 18:40
  • @MarkCh, that sounds interesting to look into! Thank you for that hint! – derM - not here for BOT dreams Jul 27 '17 at 18:51