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

Distribute QHeaderView section sizes more evenly in Stretch resize mode

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Unresolved
    • Not Evaluated
    • None
    • 5.15, 6.5, 6.6, 6.7, 6.8, 6.9
    • Widgets: Itemviews
    • None
    • All

    Description

      Currently, when using QHeaderView::Stretch as resize mode, it adjusts section sizes based on simple division, with a pixelRemainder that is continuously reduced until it's zero.

      The result is that we may end up with headers that have the sections sizes formally divided into two groups: the topmost (or leftmost) having a section size of x (normally greater than 1), and the remaining having having a size of x-1.

      While normally not a problem (for normally sized headers the visual difference is not noticeable), it can become a issue in some cases, visually but not only:

      • multiple selection by dragging in a table view will cause very different amounts of selected items for a similar amount of movement;
      • the selection of the same amount of items is not visually similar depending on their position;
      • a QHeaderView that may display groups of sections (for instance, a different background every 20 sections) will cause very different group sizes;

      I propose to use a slightly different approach for this, using a partially incremental-error based algorithm. It may not be perfect, but it's more evenly and consistently distributed along the header length.

      I applied the following approach in a custom subclass, which is called whenever necessary, including within resizeEvent of the view (forgive me, but I'm not able to write proper C++ code, so I'll simply show the basic idea as a form of pseudo-code written in Python):

      def resizeStretch(self):
          header = self.verticalHeader()
          updates = header.updatesEnabled()
          if updates:
              header.setUpdatesEnabled(False)
      
          availableSize = self.viewport().height()
          count = self.model().rowCount()
          step: float = availableSize / count
          old = 0
          for i in range(1, count + 1):
              new = round(i * step)
              header.resizeSection(i, new - old)
              old = new
      
          if updates:
              header.setUpdatesEnabled(True)
      

      The two attached images show a table with 100 rows and a size causing the viewport having a height of 350 pixels. In the first case, the default Stretch behavior is shown, in the second the above algorithm is applied using the Fixed mode. I selected 20 rows both on top and bottom.

      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
            musicamante Maurizio Berti
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes