qt - When to emit dataChanged from a QAbstractItemModel -
in qt, have model subclassing qabstractitemmodel
- it's tree displayed in qtreeview.
the model supports various forms of change work ok. 2 of relevance are:
1) data in small number of related rows changes
2) visualisation change means majority of rows should change formatting - in particular have change of background highlighting. displayrole
data not change.
the current design deals both of these in same way: every row has change model emits datachanged(start_of_row_index,end_of_row_index)
. emit signal both parent rows change , of children have changed.
however, performs badly in case 2 model gets big: large number of datachanged
signals emitted.
i have changed code in case 2 model emits datachanged
(single) row parent of entire tree.
this still appears work correctly not accord understanding of responsibilities of model. suspect may wrong.
perhaps misunderstanding datachanged
signal? cause view update children specified range? or can avoid emitting datachanged
when not displayrole
changing?
edited progress far
as jan points out, ought emit datachanged
either or of rows in case 2.
my code did emitting datachanged
every changed row expensive - view takes long process these signals.
a possible solution aggregate datachanged
signal contiguous blocks of changed rows still not perform when, example, every other row has changed - still emit many signals.
ideally tell view consider data potentially changed (but indexes still valid - layout unchanged). not seem possible single signal.
because of quirk of qtreeview
class, possible (though incorrect according spec) emit 1 datachanged(tl,br
) long tl != br
. had working , passed our testing left me nervous.
i have settled on version traverses tree , emits single datachanged(tl,br)
every parent (with tl,br spanning children of parent). conforms model/view protocol , our models typically reduces number of signals factor of 10.
it not seem ideal however. other suggestions anyone?
you expected let views know whenever data gets changed. "letting know" can happen through multiple ways; emitting datachanged
common 1 when structure of indexes has not changed; others "serious" ones modelreset
or layoutchanged
. coincidence, of qt's views able pick changes without datachanged
on e.g. mouseover, aren't supposed rely on that. it's implementation detail , subject change.
to answer final bit of question, yes, datachanged
must emitted whenever data returned qaim::data()
changes, if it's "just" other role qt::displayrole
.
you're citing performance problems. hard numbers -- getting measurable slowdown, or prematurely worried might problem later on? aware of fact can use both arguments datachanged
signal change on big matrix of indexes?
edit:
a couple more things try:
make sure view not request data. example, unless set
qtreeview
'suniformrowheights
(iirc), view have execute o(n) calls eachdatachanged
signal, leading o(n^2) complexity. that's bad.if sure there's no way around this, might away combining
layoutabouttobechanged
,updatepersistentindexes
,layoutchanged
. not changing structure of indexes, might rather cheap. however, optimization opportunity in previous point still worthwhile taking.
Comments
Post a Comment