Important: Please read the Qt Code of Conduct -

Interdependent data in a model: cached sums

  • Simplifying what I'm dealing with, I have a model made up of a table at the top level. Every row contains data regarding a user, and every "cell" should contain a list of integer (with a descriptive string attached).

    I quickly realized, however, that 99% of the time the user isn't interested in the detailed list, and rather prefers an aggregate value for every list (let's say, the sum of every value). So I decided to cache those sums to avoid calculations, putting them in the model which now looks something like this:
    // Root
    Col 0 Col 1 Col 2
    Row 0 AList(0,0) AList(0,1) AList(0,2)
    Row 1 AList(1,0) AList(1,1) AList(1,2)
    ... ... ... ...
    where AList(x,y) is a list made up of

    • aggregated value;
    • proper list;

    However, users and other external inputs aren't obviously allowed to change that aggregated value, only the values contained in the list once they ask for detail.
    I'm at a loss about how to implement this: how can I best update the aggregated value if an element of the list has been changed?

    Moreover, this is the first time I mix very different data types into the same model; is it considered a good practice as a collegue told me?

  • Lifetime Qt Champion

    @Ignis said in Interdependent data in a model: cached sums:

    how can I best update the aggregated value if an element of the list has been changed?

    Do you have a custom model or how is the data updated? If you've a custom model I don't see a problem since you then can do it in your setData() function.

  • I have ownership over the model, so I can change what I want. It's a QStandardItemModel now, but I guess I'll have to implement a custom model.

    An additional problem is that the structure is much more complicated than what I've written. That is, the model contains a lot of different data and those lists with an aggregated value are deeply nested inside the model, which in future will have a dynamic structure based on user input.

    I can think of 3 way to solve this problem:

    • marking the parent node of such lists with a special value, so that in setData() I can decide what to update. This rises the following questions: what special value? How can I avoid confusion between the marking value and normal values?
    • store a pointer to another model. As far as I understand in premade models you can't do that, but in a custom model you should be able to. This has the added benefits of making the hole thing reusable.
    • creating a parallel model structure with just one "main row" (instead of one per user) that lists the type of data contained in the proper model. This acts very much like the first option, aside from the fact that you made lookups in a different model instead of the parent of the data changed; it also avoids memory overhead and allows me to store descriptive information common to the model in a separate structure (and makes perfect sense in the architecture of the app).

    Are these solutions valid and technically viable? And are there other suitable solutions?

Log in to reply