How to design a QAbstractItemModel to support multiple object types and different views?

I need to write a QAbstractItemModel class that represents a hierarchy of different object types. I want to be able at some point, show a table/list containing only level 1 elements, only level 2, and so on.

I am working on a network protocol analyzer tool, something like wireshark. I am capturing socket.recv and socket.send events from a process. In my model those events are called NetworkEvent. Each network event may contain one or more Packet. Each packet has one or more Message, where a message, based on its code, is parsed as a defined struct.

How to design a QAbstractItemModel to support multiple object types and different views
How to design a QAbstractItemModel to support multiple object types and different views

The main window has a list and a tree. I expect to be able to show:

  1. a table/list containing only network events including its attributes.
  2. a table/list containing only packets including its attributes.
  3. a table/list containing only packets based on a network event.
  4. a tree containing a packet/message hierarchy (with fields and sub structures)
  5. a table/list containing only messages
  6. a table/list containing only messages based on a packet
  7. a tree containing a message hierarchy (with fields and sub structures).

So I thought the best idea was to model the QAbstractItemModel as a tree. First problem I encountered is that while each class has the concept of "children", each one has a different field that represents childrens, so I have to take care of that inside the QAbstractItemModel.

Also, because a table/list of Event Network doesn't have same columns as table/list of Packet, nor Message, I can't properly use the same model to define all possible ways to show the data. I suppose the correct way to do this would be defining proxy models for each kind of view.

Is there any better or easy way to approach this? Or is this the way to go?

So you create a common base family of polymorphic classes, and use a base pointer as the data source for the model. One single role - the data object, from then individual delegates can access their specific data fields without having to bother implementing everything using roles. The role-centric use-case is really only applicable for isomorphic data sets.

Then you can customize the visual representation based on the actual individual object and view type.

I wouldn't marry to any particular representation. I'd only implement a list interface, this gives more flexibility how to represent the structure, you can draw simple lists as list view or table view, and you can also have tables or trees that are made of lists of lists.

In programming, it is always a tree, which is very obvious if you structure your application well, so it is a simple manner of choosing how you visualize each node and its contents. It is common to even have different ways of visualizing the same data, both in terms of visual structure and actual delegates.

You will have a tremendously easier time implementing this in QML, especially the actual visual representation, using the generic object model outlined here. Although if your object count is very high, you might want to implement it as a single abstract item model rather than have every object be a list model to avoid the overhead. But unless you deal with millions and millions of items, the overhead is well worth the return.

Learn More :