View Full Version : QTableView with Rowspans to display hierarchical data, eliminate unnecessy space

27th January 2016, 20:15
So I have a question regarding an optimal solution for a problem facing my current project.

First a bit about what I have so far:

I have a database of hierarchical data that is being displayed in a tableview. I am using row spans to show the hierarchy, i.e. item 1 (column 0) has children 1.1 and 1.2 (column 1), item 1 has to span 2 rows so that its height encompasses both its children in the subsequent column. We do some calculations on the data to figure out what the spans should be in a pretty efficient manner, and that all seems to work fine.

The issue I've come across stems from how this is really not the kind of data that tableview was built to display, so we end up with a lot of unnecessary white-space by utilizing spans. A more accurate way to display the data would be something analogous to nesting tables in html, rather than using spans.

Here are some images to better illustrate what I'm talking about.

Current Appearance:

Preferred Appearance:

As you can see in the first image, my parent items are sizing themselves to include the rows they need to span in order to encompass their children, even if their text is long enough to encompass their children without the empty rows that are hidden behind the cell. Also the child items are sizing themselves to line up with the row the parent is on, and thus end up with a larger cell than they need if the parent text is longer.

So my question is for those that understand the inner workings of the view and delegate classes better than I do. How far would I have to go to achieve my desired result? It seems like I'd end up re-implementing TableView's paint method entirely and then probably spend ages fixing all the support methods that I break by drawing my table this way. I'm not totally opposed to directly drawing stuff if I need to, I can understand the code well enough, but I have a feeling this would be a "solution" that would cascade into other systems and probably eat up significant development time. Also I know our product owner, and this is definitely going to be an issue that they will want to be addressed, so if I'm going to argue the "not worth the time and effort for relatively little gain" angle then I'd like to at least do so from a place of knowledge and understanding. :cool:

Any light you can shed on this problem is appreciated.

29th January 2016, 15:39
The one idea I had for this problem would be to just write a whole new widget using QGridLayout as a container of sorts, then nest new QGridLayouts for child elements instead of using spans. Then I can use QLabels for displaying data, and on user clicking I can create an editor at that location.

Is that a totally crazy idea?

29th January 2016, 17:45
Is that a totally crazy idea?

Certainly sounds like one to me. And I doubt that you could reimplement the table view painting code to achieve what you want - the table view is exactly that, an x-y oriented grid of cells, where all the cells in a row are the same height and all the cells in a column are the same width. Without looking at the code, I would put money on that design being deeply embedded in the painting architecture. Your "preferred" view is just a tree view in disguise.

30th January 2016, 23:25
I'd forgotten about this: QColumnView. Sounds like what you need.

1st February 2016, 20:46
Well I appreciate your reply.

I was not aware of the QColumnView class. That may be worth looking into, but I don't know if it actually would fit my needs. I'm also not sure that treeview could represent my data correctly, but maybe I'm not looking at it from the right angle. The data in my example was really simplified. The actual data really is like nested tables.

Our actual data structure is something like this ( "Data Type Name" [ fields belonging to each item ] ):

"Item A" [Name, Description, Type]

"Item B" [Category, User]

"Item C" [Date, Author]

"Item D" [Color, Age, Location]

"Item E" [Shape, Height, Width]

Each Item A has one or more Item B as children, each Item B has one or more Item C as children, each Item B has one or more Item D as children, Each Item C has one or more Item E as children.

So basically I've got a list of items, and an item can be a field or a list of items, and I need to display it all laid out horizontally. I'm not sure if there's a name for this kind of data, but that's what I'm dealing with. If you have any other advice on a better way to tackle this problem, I would definitely appreciate it.

1st February 2016, 21:52
I suspect QColumnView might be able to handle this. It appears to add a new "major column" (my description) for each level in the tree. So you would have major columns for "A", "B", "C", and so forth. What I don't know is if it supports "minor columns" (again, my description) within a major column - so for major column "A", you would have minor columns "Name", "Description" and "Type".

Tree-structured data models can have this type of structure, I just don't know if QColumnView supports anything beyond a single column at each level. If you already have a QAbstractItemModel written for your data, plug it into a QColumnView and see what happens.

By the way, I use a QTreeView for the type of hierarchical model you have. Each level in my hierarchy has either 3 or 4 columns. Unfortunately, QTreeView expects the same column count regardless of the level in the hierarchy, so the model needs to lie when asked for the columnCount() and always return the maximum. In the data() method, the model returns an empty QVariant for the levels where there is no 4th column.

The thing that doesn't look nice is the column headings. Since the view has a fixed column count (4), the first column of each level of the hierarchy is always in column 0, second column in column 1, etc. This is why QColumnView looks like it would be a better option if it supports minor columns within major ones.