KIdentityProxyModel does nothing, fast

It has been brought to my attention that I have not blogged in a while. That usually means it’s time for a new proxy model.

The latest one is KIdentityProxyModel. It maintains an identity relationship to its source model such that the structure in the proxy mirrors exactly the structure in the source model, without sorting, filtering, flattening or otherwise changing the structure.

KidentityProxyModel in action

What the KIdentityProxyModel does provide though is a base class suitable for data proxying. There are many uses for such a class. Typically, an implementation of QAbstractItemModel will have an implementation of the data() method with a large switch statement for returning the decoration, the tooltip, the what’s-this text etc. It becomes cumbersome and difficult to maintain. Better of course is to use separate proxy models instead of a switch statement. If your tooltip text is defined in a ToolTipProxyModel, you can compile it in on the desktop, and compile it out on mobile/touch platforms where they make no sense. Similarly, you can define a DecorationProxyModel to return images of different sizes for desktop and mobile use. In KDE PIM we already use it to color the folders in kmail if you are reaching an IMAP folder size limit. Another use I have for it is to make any model have checkable items with the KCheckableProxyModel. (Ok, so I made two new proxy models 🙂 ).

KCheckableProxyModel makes check state available through a QItemSelectionModel

The primary reason for a class like this is separation of concerns, a separation of platform code and re-usable components. The overhead of using a KIdentityProxyModel is very small, so even using multiple proxies does not incur a great cost. I haven’t made any benchmarks, so I offer only proof by inspection.

After writing this class I was informed that something similar used to exist in Qt4 as QProxyModel, but was deprecated some time ago. I didn’t even know it existed. Its implementation is very similar to KIdentityProxyModel, but an important difference is that KIdentityProxyModel implements QAbstractProxyModel, while QProxyModel implements QAbstractItemModel. That means that chaining is possible with KIdentityProxyModel, but not with QProxyModel.

4 Responses to “KIdentityProxyModel does nothing, fast”

  1. Michael Filonenko Says:

    Are you use reintepret_cast for QModelIndex to access “model” member to fast mapping to/from source?

  2. steveire Says:

    Yes, that’s how it works. Not pretty, but the binary interface of QModelIndex can’t change now, so it should always work.

  3. Practicing what I preach « Steveire's Blog Says:

    […] unrelated to the code causing the bug because a segfault or assert will occur later. Although KIdentityProxyModel appeared in the above backtrace it was unrelated to the problem. Assert as early as possible if you […]

  4. Watching my Ks and Qs « Steveire's Blog Says:

    […] originally wrote KIdentityProxyModel with the intent of putting it into Qt on request. Once it gets into Qt I’m no longer the […]

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: