Gonzalo Fernandez
Gonzalo Fernandez

Reputation: 85

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.

Here is an image of the program class hierarchy:

class hierarchy

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

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 EventNetworkdoesn'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?

Upvotes: 1

Views: 922

Answers (2)

jwernerny
jwernerny

Reputation: 7048

I think you are on the right course with thinking of using multiple proxy models, one for each table. I would suggest starting with QSortFilterProxyModel and implement your own filtering algorithm.

I will also suggest you might want to identify the type of data with using custom Qt::ItemDataRole enumerations, one for each type. I think it will make the filtering easier.

You may want to experiment with List, Table, and Tree Views to see which suits your purpose the best. The beauty of the Model-View system is you can easily change the View once you have the model(s) down.

Upvotes: 0

dtech
dtech

Reputation: 49319

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.

Upvotes: 1

Related Questions