[Interest] Best practice for properties, QAbstractListModel with a QList<QObject*> and a Quick2 view

Jan Kundrát jkt at flaska.net
Wed Dec 18 14:58:17 CET 2013


On Wednesday, 18 December 2013 11:59:15 CEST, Ola Røer Thorsen wrote:
> However I get problems when I delete objects from the list model. The
> delegates are deleted later than the actual objects, so I get warnings 
from
> QML on the console (saying myObject is null). These seem harmless enough,
> but I would like to avoid having any warnings at all.

When working with the QAbstractItemModel, items can only be deleted via 
resetting the model, or when removing rows/columns. The row/column removal 
shall happen in three phases:

1) call beginRemoveRows
2) remove the internal representation, freeing the MyObject instances
3) call endRemoveRows

I will argue that if a delegate is alive after the beginRemoveRows 
finished, then the QML view is broken. The view shall react to 
rowsAboutToBeRemoved and kill any delegates in response to that signal.

However, you absolutely must not free your internal representation prior to 
calling beginRemoveRows. Are you sure that this is not the case?

> Item {
>    id: theDelegate
>    property string someValue: myObject ? myObject.someObjectValue : ""
> }
>
> but this is just ugly.

Something is apparently picking up some signal which causes the delegate to 
notice that the value of "myObject" has changed. What signal is it? Are the 
delegates alive even after rowsAboutToBeRmoved is emitted?

> The alternative is to create roles for every property in MyObject, and
> connect signals for every one of them so the model updates when one of 
the
> properties changes. Perfectly doable of course, but it has to be kept
> up-to-date with the properties in MyObject, and feels like duplicating a
> lot of code.

It's interesting that you've solved the problem of too many roles by using 
a QObject instance within the model itself. I wonder whether this is 
actually a good path -- QObjects are rather heavyweight, so it is a 
question whether you gain anything by trading the disadvantage of "got to 
call the model's data() too many times, once for each role" by another 
problem, "got to manage expensive QObjects instead of some liteweight 
internal nodes".

Perhaps it fits the rest of the code and using QObjects "inside" the model 
makes sense. However, if that was not the case, simply emitting 
dataChanged() when any "property" changes migth be even easier (and would 
elliminate the need to use properties and separate signals in the first 
place).

With kind regards,
Jan

-- 
Trojitá, a fast Qt IMAP e-mail client -- http://trojita.flaska.net/



More information about the Interest mailing list