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

QTableView is slow when receiving a dataChanged where topLeft != bottomRight

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3: Somewhat important
    • Resolution: Done
    • Affects Version/s: 5.6.0, 5.7.0, 5.7.1, 5.8.0
    • Fix Version/s: None
    • Component/s: Widgets: Itemviews
    • Labels:
      None
    • Commits:
      8de62d34321cd827e60b0a7b6e7434070de301ae (qt/qtbase/dev)

      Description

      If the topLeft index and bottomRight index received by the dataChanged slot in QAbstractItemView do not match then entire view is repainted rather than just the changed cells, if they do match only one the changed cell is repainted.

      qabstractitemview.cpp
      void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
      {
      ...
          if (topLeft == bottomRight && topLeft.isValid()) {
      
      ...
      
              if (isVisible() && !d->delayedPendingLayout) {
                  // otherwise the items will be update later anyway
                  update(topLeft);
              }
          } else {
      
      ...
      
              if (isVisible() && !d->delayedPendingLayout)
                  d->viewport->update();
          }
      }
      

      With a model containing around 200 rows and 50 columns, receiving approximately 10 updates a second where multiple adjacent columns on the same row were changing I was seeing a CPU load of 50%, when the QTableView was open, by changing the model to emit individual dataChanged calls even when all items are adjacent this load dropped to 5%.

      Subclassing QTableView and implementing the following override also had the same effect.

      void MyTableView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
      {
          for(int row=topLeft.row(); row <= bottomRight.row(); ++row)
          {
              for(int column=topLeft.column(); column <= bottomRight.column(); ++column)
              {
                  QModelIndex index = topLeft.sibling(row, column);
                  QTableView::dataChanged(index, index, roles);
              }
          }
      }
      

      This issue should impact QListView and QTreeView as well.

        Attachments

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

          Activity

            People

            Assignee:
            qt.team.quick.subscriptions Qt Quick and Widgets Team
            Reporter:
            jtjbrady Jonathan Brady
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes