PDA

View Full Version : ProxyModel or 'own' Data Model?



norzaw
14th February 2017, 23:27
Hi!

I was already searching the net a lot but couldn't find an answer to my actual problem. So I'll try here...

I have a simple data-structure, a two-dimensional List (here very reduced to keep it simple): A QList<event>, every event contains a timestamp and a QList<items>, every item just text + value

Now in the window a have 2 views, a QTreeView and a QTableView

I've set up a data model for the TreeView and the TreeView displays the data as a tree of depth 2 (works nice):


-timestamp, ...
item1 3
item2 1
item5 8

-timestamp, ...
item1 1
item3 1
item5 5


Now the TableView shall display summary calculations of the same data in the form


ITEM SUM
------------------
item1 4
item2 1
item3 1
item5 13


Now I wonder which approach would be the "right" one? Use a ProxyModel to "map" the TreeModel to the TableModel and do the summary calculations in the ProxyModel?
Or give the TableView a TableModel which "uses" the TreeModel's data?

Thanks for any answers!

high_flyer
15th February 2017, 00:10
Now I wonder which approach would be the "right" one? Use a ProxyModel to "map" the TreeModel to the TableModel and do the summary calculations in the ProxyModel?
Or give the TableView a TableModel which "uses" the TreeModel's data?
In my view a TableModel that uses the TreeModels data IS a proxy model, just I guess you mean doing it manually (populating your TableModel manually).
I would go with QSortFilterProxyModel - it will allow you to concentrate on the important stuff - the end result in your table view.
You can filter all the multiple occurrences, and while doing it counting them as well.

anda_skoa
15th February 2017, 10:03
I would go for two models working on the same data, no need for either to know the other.

They are both interpreting the data in a different way, not just structuring it differently.

Cheers,
_

d_stranz
15th February 2017, 18:18
I vote with anda_skoa. I have written code that "flattens" a multi-level tree model into a table, and it is very hard to get it right, especially if you want to handle selections from either the table or the tree in a reciprocal manner (e.g. selecting in the tree selects the corresponding rows in the table and vice versa). If the underlying data is simple, it is better to create two models to work off it.

There is a kptflatproxymodel in KDE that does map a tree into a table, so if you really want to go that way you could probably adapt it.

high_flyer
16th February 2017, 17:02
especially if you want to handle selections from either the table or the tree in a reciprocal manner (e.g. selecting in the tree selects the corresponding rows in the table and vice versa).
This argument is not clear to me, if anything its an argument to use a proxy.
The reason being that if you have two separate models, you have to take care of selection on both of them - and since a proxy uses the same underlying items from the source model, selecting in the proxy selects in the original as well.
Other draw backs for two models is harder to test, harder to maintain, and adds another bug source (the mapping code).
But at the end there is no "right answer" - it all depends on your needs and situation.
Probably in this case, what every seems easier is the better choice if its not a production or large project.

d_stranz
16th February 2017, 20:00
This argument is not clear to me, if anything its an argument to use a proxy.

Which is in fact what I did, an adaptation of the KDE flat proxy. It's been a while, but my recollection is that the KDE proxy did not have support for mutual selection, so getting all that to work properly was painful. If I was to do it again, I would probably not use a proxy and implement some sort of external mapping.

anda_skoa
17th February 2017, 11:07
and since a proxy uses the same underlying items from the source model, selecting in the proxy selects in the original as well.

Each view would work with a different model (one with the proxy, one directly with the source model), their QItemSelectionModel instances would work with different indexes, no?

Cheers,
_

d_stranz
17th February 2017, 19:20
Each view would work with a different model (one with the proxy, one directly with the source model), their QItemSelectionModel instances would work with different indexes, no?

Exactly, and this is one of the difficulties in synchronization - you need to map one index back up to the original tree model and then back down to the corresponding index in the table model (if selecting from the tree) or from the table model up to the tree model (if selecting from the table).

My actual use case is worse than that - not only do I have a tree -> table flattening, I also allow sorting and rearrangement of table view columns as well as additional proxies and views that I use to plot pairs of columns from the table in graphs. So selecting from the tree means mapping to the sorted table proxy to the flat table proxy and then to each of the proxies that filters the flat table for the graphs. Selecting a point from a graph involves reversing that whole process to highlight the corresponding original item in the tree.

Nearly two years later, I'm still trying to track down bugs.

high_flyer
20th February 2017, 01:01
Indeed you are right guys.
Found this interesting thread about it, might be helpful for the OP:
https://forum.qt.io/topic/6139/best-practice-for-sharing-selection-model-and-proxy-models-with-multiple-views/5

d_stranz
20th February 2017, 18:14
Thanks for the really useful link.