Sharing a QItemSelection between views through proxy models

It is possible to share a QItemSelectionModel between two different views, and therefore to share the selection between both. The technique is used in the Chart example and the interview demo.

A QItemSelectionModel can be shared between views

However, in a complex application, it’s not as simple as a model and a view or two. Eventually someone finds an excuse to add a proxy model, but then you can’t share the selection anymore. If you try it you get a runtime error:

QAbstractItemView::setSelectionModel() failed: Trying to set a selection model, which works on a different model than the view.

QitemSelectionModel can not be shared when using a proxy model

The problem is that a QItemSelectionModel operates on one particular model, so views manipulating the selection through it need to be operating on the same particular model. When a selection is made, the indexes which are part of the selection get painted a different colour, so something in the system needs to know of the existence of the proxy model and do the mapFromSource work.

Luckily enough, the designers of the Qt Model View system had the foresight to make some methods of QItemSelectionModel virtual, such as select. That means that when a selection is made through the view, we can do something else than select the indexes, or something supplemental such as a mapToSource call.

The KProxyItemSelectionModel inherits and overrides the QItemSelectionModel methods to encapsulate the concept of "When a selection is made, proxy the selection to another selection model and vice-versa".

KProxyItemSelectionModel proxies selection to another QItemSelectionModel

It works in both directions, so a selection through either view is forwarded to the other. There is a sufficient amount of voodoo, documented with ASCII art, to allow arbitrary configurations of proxy models to be traversed as long as they share a common source model somewhere along the line.

Complex proxy structures are traversed automatically be KProxyItemSelectionModel

That’s not the only trick you can play with QItemSelectionModel. More in a later post.

Update: The KProxyItemSelectionModel has been renamed KLinkItemSelectionModel.

4 Responses to “Sharing a QItemSelection between views through proxy models”

  1. Andreas Says:

    Nice, except that the API dox basically don’t exist. Its completely unclear to me what I’d be passing to the constructor for example. I think it would be nice to include the necessary code for both the simple and the complex example you’ve drawn in the API dox.

    • steveire Says:

      Yes, I will update the apidox. I stared by adding the images to the dox, but api.k.o hasn’t been updated yet.

  2. Breadcrumbs for your view « Steveire’s Blog Says:

    […] Steveire’s Blog Just another weblog « Sharing a QItemSelection between views through proxy models […]

  3. Navigating a QAbstractItemModel tree in a QML view « Steveire’s Blog Says:

    […] Implementing this concept was actually the motivation behind developing a ui independent breadcrumbs list and a method of proxying selections through complex systems. […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: