PDA

View Full Version : QTableView spanning bug when moving column to a different visual index



forgottenduck
10th November 2016, 15:55
So in my current project we have a large tableview with many columns, with a hierarchical data structure which we represent by using row spans on items in the table. We also do some custom size calculation to get the table to display at minimum vertical height. That all works great, but we recently discovered that when one of our items spans multiple rows, and is moved to a different position within the table, the cell is not drawn correctly. After pouring through our code base trying to discover where we went wrong, I realized that this bug is evident in even very simple code, which you can see below. You can copy this code into the mainwindow.cpp file in a new Qt Widgets application, and see the bug for yourself. Just run the application, and notice that depending on the size of your window, the column labeled as span will display with no span. Essentially if there is a scrollbar, the cell does not display correctly. If you switch to full-screen the cell displays correctly. You'll also notice that the editor does expand to the correct size.




ui->setupUi(this);


QTableView* tableView = new QTableView;
setCentralWidget(tableView);

QStandardItemModel* model = new QStandardItemModel;

model->setColumnCount(15);
model->setRowCount(10);
model->setHeaderData(0, Qt::Horizontal, "Span");

tableView->setModel(model);

tableView->setSpan(0,0, 10, 1);

tableView->horizontalHeader()->setSectionsMovable(true);

tableView->horizontalHeader()->moveSection(0, 8);



I'm hoping someone can't point out how to fix this the "correct" way because I have a workaround in mind, but I would prefer to understand the problem. I did a few tests in the larger scope of my application where I have custom delegates and such. I found that, when the cell is drawn incorrectly, the QStyleOption argument of the paint method for my delegate has the incorrect size stored in the rect. I can fix this by calling visualRect() on the cell being painted, and the view does return the correct size. However applying that to the drawing rect only makes the cell draw itself correctly, the table grid lines still overlap it as if it has no span. I know I can turn off grid lines, and I'm sure I can find some way to draw the grid lines myself correctly, but it would be nice if I could rely on the built in methods. Also I'm not a fan of calling visualRect() from within my delegate because it means I need to make a pointer to my table view class inside my delegate, or I need to cast the option.widget in the paint method each time and then call visualRect, and I'm concerned about performance because these are rather large tables with lots of HTML rendering.

Also in my search for a solution I did turn up this bug report (https://bugreports.qt.io/browse/QTBUG-4319), which could be related, it at least sounds like the same issue, and it doesn't seem like it was resolved. It seems crazy to me that this is not a more prevalent problem. Do people not use the span feature that often?

Anyway, any help that can be offered is appreciated. Thanks for reading.

forgottenduck
11th November 2016, 02:19
I'm hoping someone can't point out how to fix this the "correct" way

Definitely meant can. :D