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

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

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: P3: Somewhat important P3: Somewhat important
    • None
    • 5.6.0, 5.7.0, 5.7.1, 5.8.0
    • Widgets: Itemviews
    • None
    • 8de62d34321cd827e60b0a7b6e7434070de301ae (qt/qtbase/dev)

      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.

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

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

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes