Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.13.0 Alpha 1
-
None
Description
The following program reproduces the issue:
#include <QApplication> #include <QHeaderView> #include <QTableView> #include <QStandardItemModel> int main(int argc, char** argv) { QApplication app(argc, argv); QTableView table; auto model = new QStandardItemModel; model->appendRow({ new QStandardItem("Lorem ipsum dolor sit amet, "), new QStandardItem("consectetur adipiscing elit ")}); auto header = table.horizontalHeader(); header->setSectionResizeMode(QHeaderView::ResizeToContents); QObject::connect(header, &QHeaderView::sectionResized, [header](int i, int old_size, int new_size) { printf("section %d resized from %d to %d\n", i, old_size, new_size); for(int i = 0; i < header->count(); i++) printf(" section %d size %d position %d\n", i, header->sectionSize(i), header->sectionPosition(i)); }); table.setModel(model); table.show(); return app.exec(); }
When I run that program , I get the following output to stdout:
section 0 resized from 105 to 210 section 0 size 105 position 0 section 1 size 105 position 105 section 1 resized from 105 to 196 section 0 size 210 position 0 section 1 size 105 position 210
After the sections are resized from 105 (which I assume is their default value) to 210 and 196, signal sectionResized is emitted twice, once for section 0 and once for section 1. You can see that in the first call of the slot connected to that signal, sectionSize(0) and sectionPosition(1) return wrong values. In the second call of the slot, sectionSize(1) returns the wrong value. This behavior occurs not only during the initialization, but also when sections are resized at a later time (as long as sectionResizeMode is ResizeToContents), as attached file example.cpp demonstrates.
I would expect that when sectionResized is emitted, at least sectionSize(logicalIndex) would return the new value. The fact that it doesn't is surprising and can lead to hard to find bugs.
The issue seems to be in QHeaderViewPrivate::resizeSections. In that method, there is a loop that takes care of updating SectionItem objects and emitting signal sectionResized. It emits the signal for section with visual index i in its ith iteration, but it updates the corresponding SectionItem object in a later iteration, after it has reached a section with a different new length (if there is no such section, the SectionItem object is updated after the loop is finished). Therefore, the SectionItem object still contains outdated values when signal sectionResized is emitted for the corresponding section.