Qt
  1. Qt
  2. QTBUG-13668

When dataChanged() is emitted with indexes indicating a range, then the whole viewport will be updated

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: P2: Important P2: Important
    • Resolution: Invalid
    • Affects Version/s: 4.6.3, 4.7.0
    • Fix Version/s: None
    • Component/s: Widgets: Itemviews
    • Labels:
      None

      Description

      When dataChanged() is emitted with indexes indicating a range, then the whole viewport will be updated as the range is not taken into consideration. If only a single index is covered by the "range" indicated in the emitted signal then it only updates that index.

      Attached is an example that reproduces the problem, the signal is emitted with only rows 2-3 in the range yet all of the rows are updated. The reason it shows a QListView and a QTreeView is if you change it to emit only a single index in the range, then QTreeView works correctly, whereas QListView still doesn't.

      1. main.cpp
        1 kB
        Andy Shaw (closed Nokia identity)

        Issue Links

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

          Activity

          Hide
          Jens added a comment -

          dataChanged is not documented to work as you suggest. Even if you hint to it that only a few rows have changed, this doesn't mean that the view cannot update all of them. It is up to the view to decide what is most efficient. If you implement your own view, you can use this information.

          Show
          Jens added a comment - dataChanged is not documented to work as you suggest. Even if you hint to it that only a few rows have changed, this doesn't mean that the view cannot update all of them. It is up to the view to decide what is most efficient. If you implement your own view, you can use this information.
          Hide
          Andy Shaw (closed Nokia identity) (Inactive) added a comment -

          I re-read the documentation and I see your point about it not actually documented in that way, however that is the implication that I got. The views themselves should probably be documented to point out how they actually respond to dataChanged() as its not necessarily how people would expect it to be and then they can at least handle dataChanged in a way that will work in the way that they want. For example with QTreeView you could just emit the signal for each index to ensure only those specific ones are updated.

          Show
          Andy Shaw (closed Nokia identity) (Inactive) added a comment - I re-read the documentation and I see your point about it not actually documented in that way, however that is the implication that I got. The views themselves should probably be documented to point out how they actually respond to dataChanged() as its not necessarily how people would expect it to be and then they can at least handle dataChanged in a way that will work in the way that they want. For example with QTreeView you could just emit the signal for each index to ensure only those specific ones are updated.
          Hide
          Robert Dooley added a comment -

          This also happens with QTableViews.
          The workaround of calling dataChanged() with single QModelIndex values fails when a "QSortFilterProxyModel" is added and the view has "sortingEnabled" set to true.

          Show
          Robert Dooley added a comment - This also happens with QTableViews. The workaround of calling dataChanged() with single QModelIndex values fails when a "QSortFilterProxyModel" is added and the view has "sortingEnabled" set to true.
          Hide
          Nicholas Chapman added a comment -

          I think this bug should be re-opened.

          I have run into it with a QTreeView.
          When emitting a dataChanged signal on the underlying model (QAbstractTableModel), if the index range is just a single element, e.g. range begin = range end, then only that item is invalidated. However if the index range is more than a single element, then the whole visible rectangle of the QTreeView is updated.

          This seems grossly inefficient.

          This could probably be fixed by forming a rectangle containing the begin and end elements of the range, and invalidating that rectangle.

          Show
          Nicholas Chapman added a comment - I think this bug should be re-opened. I have run into it with a QTreeView. When emitting a dataChanged signal on the underlying model (QAbstractTableModel), if the index range is just a single element, e.g. range begin = range end, then only that item is invalidated. However if the index range is more than a single element, then the whole visible rectangle of the QTreeView is updated. This seems grossly inefficient. This could probably be fixed by forming a rectangle containing the begin and end elements of the range, and invalidating that rectangle.
          Hide
          Giuseppe D'Angelo added a comment -

          Thorbjørn Lund Martsum, Olivier Goffart (Woboq GmbH), do you happen to know why the code in QAbstractItemView::dataChanged looks like that in case of a range of indices?

          Show
          Giuseppe D'Angelo added a comment - Thorbjørn Lund Martsum , Olivier Goffart (Woboq GmbH) , do you happen to know why the code in QAbstractItemView::dataChanged looks like that in case of a range of indices?

            People

            • Assignee:
              Thierry Bastian (closed Nokia identity) (Inactive)
              Reporter:
              Andy Shaw (closed Nokia identity) (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Gerrit Reviews

                There are no open Gerrit changes