In Qt, I have a subcategory of the QAbstractItemModel model - this is the tree displayed in QTreeView.
The model supports various forms of change that all work fine. These two values are:
1) Some data in a small number of related rows is changed
2) Changing the visualization means that most lines should change their formatting - in particular, they have a change in the background of the backlight. Their DisplayRole data does not change.
The current construct deals with both of them the same way: for each row that has any change, the model emits dataChanged(start_of_row_index,end_of_row_index) . I emit a signal for both parent lines that are changing, and for any of their children that have changed.
However, this does not work well in case 2 as the model becomes large: a very large number of dataChanged signals are dataChanged .
I changed the code, so in case 2, the model emits dataChanged only for the (single) row, which is the parent for the whole tree.
This seems to work correctly, but does not match my understanding of model responsibilities. But I suspect that I could be wrong.
Perhaps I misunderstand the dataChanged signal? Does this really cause the view to update all children, as well as the specified range? Or can I avoid emitting dataChanged when not DisplayRole changes?
Edited by my progress so far
As Jan points out, I have to emit dataChanged for most or all rows in case 2.
My code initially did this by emitting dataChanged for each changed row, but it is too expensive - it takes too long to scan to process all these signals.
A possible solution would be to combine the dataChanged signal for any adjacent blocks with changed rows, but this will still work poorly when, for example, every other row has changed - it will still emit too many signals.
Ideally, I would just like to show the view that all data is potentially changed (but all indexes are still valid - the layout has not changed). This is not possible with a single signal.
Due to the quirk of the QTreeView class, it is possible (albeit incorrect according to the specification) to emit only one dataChanged(tl,br ) while tl != br . I had this job, and it passed our testing, but left me nervous.
Now I settled on the version that traverses the tree and produces a single dataChanged(tl,br) for each parent (with tl, br covering all the children of this parent). This complies with the model / presentation protocol, and for our models it usually reduces the number of signals by about 10 times.
However, it is not perfect. Any other suggestions anyone?