PDA

View Full Version : Synchronizing selections in filtered and non-filtered model views



ghorwin
19th September 2007, 16:31
Hi there,

I have created a model that sources from some data source, and a filter proxy that filters the data provided by the model:

data -> model -> filter_proxy_model

I also have 3 views, the first two show the filtered data (they use filter_proxy_model) and the last one shows the unfiltered data (uses model directly).

Now I want to synchronize selections between the three views, and naturally, if I select something in view 3, that is fully or partially filtered out in view 1 and 2, the selection in these views should be reduced accordingly.

What's the best way to do that? Simply assigning a QItemSelectionModel created for the filtered view to all three views doesn't to the job. It seems that I need some kind of ItemSelectionProxyModel as well...

What are your recommendations?

Andreas

wysota
19th September 2007, 16:55
Unfortunately there is no simple solution to that. You need to connect to selectionChanged() signal of both (filtered and unfiltered) selection models and update the other selection model accordingly using mapToSource() and mapFromSource() of the proxy model.

ghorwin
20th September 2007, 12:57
Works well, except that because of the filtering, the QItemSelection objects need to be transformed just in a list of model indices disregarding the invalid ones. And then there doesn't seem to be an easy way to combine them back into a QItemSelection to reduce the number of model indices again. So, the performance benefit of using QItemSelection is essentially lost.

Also, the QItemSelectionModels tend to ping pong their change events so one has to manually disable the event while synchronizing the selections. But after all, it works.

wysota
20th September 2007, 13:01
Or you could just check if the new selection you want to apply is different than the old one.

ghorwin
20th September 2007, 13:11
Hmm, this will still give you an unwanted ping-pong. For instance, when you make a drag/range selection in the unfiltered model view, this will create one QItemSelection object. However, when I set the selection in the filtered view, where some of the elements in the range are not present, this will become a list of single QModelIndices that are selected. Now, the filtered ItemSelectionModel pings it back to the unfiltered view but now I get a list of singe model indices vs. the current single QItemSelection model. So, I must assume a new selection was made and pong the filtered version back to the filtered model.

So, blocking the selection events (just by setting a flag) is working out best and is also faster than comparing a potentially long list of selections.

Unless someone has a good idea how to avoid this manual selection-synchronizing alltogether?