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

[REG 6.5.2->6.5.3] QAbstractScrollArea::sizeHint does not include the horizontal scrollbar's size

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P1: Critical
    • None
    • 6.5.3, 6.6
    • None

    Description

      Context

      I first made a minimal reproducible example to demonstrate how tables resize infinitely when added to a QVBoxLayout alongside a spacer:

      QWidget widget;
      QVBoxLayout layout(&widget);
      QTableWidget *tableWidget = new QTableWidget;
      
      //random filling to get a size and resizing
      tableWidget->setColumnCount(6);
      tableWidget->setRowCount(10);
      //the dynamic resizing allows the bug to appear
      tableWidget->setSizeAdjustPolicy(QTableWidget::AdjustToContents);
      //to make the table actually adjust (expand, in this case, to be precise)
      tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
      tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);    
      
      layout.addWidget(tableWidget);
      layout.addStretch();
      widget.show();
      
      //to make it flicker automatically
      //also possible to resize manually to test different sizes
      widget.resize(tableWidget->minimumSizeHint().width(), widget.height()+tableWidget->height());    
      
      QObject::connect(tableWidget->verticalScrollBar(), &QScrollBar::rangeChanged, [tableWidget]()
      {
          qDebug()<<tableWidget->sizeHint();
      }); 

      Findings

      However, after testing different Qt versions, I discovered that it last worked correctly in Qt 6.5.2, which led me to search for what changes were introduced in Qt 6.5.3, and found these:

      This bug seems to be caused by a typo (copy-paste error maybe).

      Qt 6.5.2:

      QSize QAbstractScrollArea::sizeHint() const{    
          /*
              preevious code
          */
          const bool vbarHidden = d->vbar->isHidden() || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
      
          const bool hbarHidden = d->hbar->isHidden() || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
          /*
               next code
          */
      } 

      Starting from Qt 6.5.3:

      QSize QAbstractScrollArea::sizeHint() const{
          /*
              preevious code 
          */
          const bool vbarHidden = !d->vbar->isVisibleTo(this) || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
          //     this should be "h" ->V
          const bool hbarHidden = !d->vbar->isVisibleTo(this) || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
          /*
              next code 
          */
      }  

      It checks whether the hScrollbar is visible using vScrollbar. Combine that with the spacer expanding, and it causes the table to shrink, but the hScrollBar will still take space, causing the vertical one to appear (d->vbar->isVisibleTo(this) == true); the size is then "corrected", the vScrollbar disappears. Rinse and repeat.

      Suggestions

      I added two checks to the unit test from the mentioned bug fix. One for each scrollbar, if it's correctly taken into account by sizeHint. Just comparing the sizeHint with/without the scrollbar. I've also attached a standalone unit test for this specific bug.

      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
            abderrahmene_rayene Abderrahmene Mihoub
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes