Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-74502

QHeaderView method sectionSize returns a wrong value when called from a slot connected to sectionResized

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • 5.13.0 Alpha 1
    • Widgets: Itemviews
    • None
    • Linux/X11, Windows

    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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            jkrempus Jernej Krempuš
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes