I am having some problems to model my data using QAbstractItemModel. I have read Model/View Programming page, and while I understand how it works I still dont know how to adapt this to my project. I also have searched for examples/open source programs but no luck.

I am working on python using PySide2 but I dont have problems reading c++ code. I will put a link at the end to my github project. Because of this question, the project is still a prototype, so dont expect high quality code.



What is this project about:
I am developing a tool to reverse engineering network packets, something like wireshark but different with scope. I need to import a file and show that data to the user. Each line on that file represents a "network event" (socket recv/send function).
A line look like this:
Qt Code:
  1. {""timestamp":"2019-Jan-27 05:34:40", "server":"192.240.44.240:27701", "source":"Server", "packets":["0500020001230300420100", "0788F276A1"]}
To copy to clipboard, switch view to plain text mode 
So basically a NetworkEvent consist of a timestamp, server address, source and a set of packets.
Each packet is a struct and will be parsed using autogenerated code that I dont have control. A packet or it nested structs is a:
StructItem:
- Name
- Value (can be null)
- Root (struct in the top of this hierarchy. Will always be a packet)
- Parent (parent struct)
- Members (nested structs. Emtpy if this struct represents a primitive data type)
- Start Pos (position of this structure in the packet byte array. Null in root)
- End Pos (end position of this structure in the packet byte array. Null in root)
- Byte array (only present in root. Null in childs)
- NetworkEvent (network event which this structure is part of)

Based on this data, I want to show to the user:
- A table/list (QTreeView) with all network events, with their respective timestamp, server address, source and number of packets.
- A tree (QTreeView) showing structure of packets from current selected NetworkEvent on the table.
- A hex viewer (QAbstractScrollArea/QAbstractItemView) showing binary data of current selected packet.

Features I want to implement:
1- In the hex viewer, hightlight bytes related to the selected field on the tree view. If hex viewer data doesnt correspond to clicked node root (Packet), update hex viewer data. (This is why I want to use QAbstractItemView for hex viewer)
2- In the tree view, select a node which correspond to the clicked bytes on the hex viewer.
3- TextEdit to filter Packets (and so on NetworkEvents) based on any packet field (or fields on its nested structures).
4- TextEdit to Filter NetworkEvents based on its fields.
5- Open a non-modal dialog to show a packet object tree and bytes (hex viewer), supporting features 1 & 2.

Things I would like to implement at some point:
6- Have a option to remplace the EventList with a list of Packets or some common nested struct available in all packets (as it seems, a packet its compossed of messages. Message class is autogenerated, to the program, its just another StructItem.). This is desirable but not required.

Picture of the program
This is a picture of what my program looks right now:
example.jpg



The question: how should I implement QAbstractItemModel to support those features?

What I have done:
I will explain then what I have done, but it is possible that I overthinked (and that is why I am asking here), and this may make no sense. Feel free to skip.

Currently I have created a BaseModel : QAbstractItemModel that serves as a Tree. Its root index is a dummy node that has as childs the list of NetworkEvents. A NetworkEvent has as child a StructItem. A StructItem has as childs others StructItems (no childs in case of leafs).

Because my business model doesnt has a "childrens" field, I have created wrapper classes (NetworkEventNode and StructNode, both based on a base class Node) that hides this behavior, so to the BaseModel it is transparent. A StructItem in NetworkEvent.packetList is a child of a NetworkEvent. A StructItem in StructItem.members is a child of a given StructItem. Should the model interact directly with business model? In that case, BaseModel should be responsible to know which field of NetworkEvent represent its childs and which field of StructItem represent its childs.

Because columns in the List/Table (QTreeView) arent common to all nodes in the BaseModel, I created a EventListModel (proxy model based on QIdentityProxyModel) that modifies BaseModel behavior to work as a table and provides access to NetworkEvent object members.
Same goes for the Object tree (QTreeView). It only shows nested StructItems, but its rootIndex is a NetworkEvent(Node), so I created a ObjectTreeModel (proxy model based on QIdentityProxyModel) that is the responsible to provide support to that Object Tree.
Currently, the hex viewer is not based on model/view but I want to change that, so it is possible to use QModelIndexes to communicate with Object Tree.

To implement the filter, I would have to insert another proxy model (QSortFilterProxyModel) between current proxy models and base model.

Now I dont feel confident continuing with this. I feel like I am overthinking and not sure if this is the way to do what I need. Should I separate the "BaseModel" in two different models? One that supports the list and another that supports object tree? What about the future HexViewer based on QAbstractItemView, should it have its own model or just have as root index the QModelIndex of selected packet in object tree?

I would like if anyone with more experience can guide me to the right path.


Link to my project: https://github.com/FYGonzalo/packet_analyzer