View Full Version : Treeview scrollbar not updating when inserting rows

Khal Drogo
15th November 2007, 09:31

I really hope i can find an answer here.

I have the following problem:
A worker thread is feeding data at a high rate to my main(gui) thread. I add the data to my model per row (i receive a structure which contains the data of an entire row). I use the beginInsertRows and endInsertRows functions.
In my view i have reimplemented rowsInserted, so i have control when to update the view. I.e. if the data is not actually visible, then the viewport should not be updated, otherwise the result will be that the cpu is constantly at 100%.
The problem is the following:
Although this quite visibly solves the high cpu usage, it also has the following undesirable effect:
It doesnt update the vertical scrollbar. For example, lets say in my view i can fit 10 rows, visually. From the 11th onward, the scrollbar doesnt resize itself. If i sort, filter, etc., the scrollbar resizes to represent the number of the rows at that moment, but it doesnt resize afterwards.

I have tried updating manually the scrollbar. Unacceptable jittery results.
In conclusion, i need a solution, that *always* updates the vertical scrollbar, but it doesnt try to update the view if the added item is not visible.

Thank you in advance.

15th November 2007, 10:34
How do you deliver the data into GUI thread? You are not touching GUI from a worker thread, right?

Khal Drogo
15th November 2007, 10:50

Of course not. I registered the data type and im sending through the signals/slots mechanism.
It arrives ok, and i insert it in the model.
The issue which i described presents itself after this step.

Thank you for your reply.

15th November 2007, 11:01
Do you call the base class implementation of rowsInserted() when appropriate eg. when you actually want to update?

Khal Drogo
15th November 2007, 11:16
Yes, i call it, when the rows would be visible, but not when it lies outside the visible area.

15th November 2007, 14:22
Hmm, try calling QTreeView::updateGeometries() [undocumented, protected] which further calls QTreeViewPrivate::updateScrollBars().

Khal Drogo
15th November 2007, 14:35
Thanks for the suggestion, i've tried it, but no success.
Basically, no change, whatsoever.

15th November 2007, 15:03
Looks like QTreeView maintains its private "view items" structure which gets out of sync due to reimplemented QTreeView::rowsInserted(). Perhaps you should forget about reimplementing it and try to deliver the data in some kind of batches instead of continuous flow.

Khal Drogo
15th November 2007, 15:14
Thats bad news, i really need to keep the flow as fast and as continuous as possible.
I know of no other way of making only those items update which are visible, than that presented. Because this *has* to happen in order not to freeze up the gui, or keep the cpu continually at 100% when visually nothing happens. And this has the scrollbar problem.
Do you have another solution suggestion, perhaps?

Thanks very much for your assistance.

15th November 2007, 18:07
So updating at every received row is too much overhead, and updating never causes the scrollbars to be out of sync. So why don't you just update periodically? Update twice a second or so. Should keep the cpu usage manageable, and the scrollbars will be reasonably up to date..

Although it sure sounds like there should be a better solution to this problem...

15th November 2007, 18:12
Also you can perhaps try minimizing the cost of updates by setting uniformRowHeight and making sure the header is not set to ResizeToContents

Khal Drogo
29th November 2007, 14:13
Thank you, pherthyl, albeit a little late on my thanks :)
I used most of your solutions, though i dont really know a correct way of forcing an update on the view every 1-2 seconds. Maybe by giving a model a list of visible mapped to source indexes(because i use a proxy model aswell) to emit dataChanged on all of them?
I ended up buffering the row inserting on the model side, and emitting beginInsertRows/endInsertRows on every 20 inserts.