PDA

View Full Version : QListView unresponsive when painting images



isplasher
4th May 2015, 18:03
Hello
I have set up a QAbstractListModel together with a QStyledItemDelegate and QListView.
In the model i have a method called "populate" which will search the local disk for some data, and then append it to the data list in the model via a signal. The signal invokes layoutChanged() (don't know how to use dataChanged anywhere except in the obligatory data method), which will then refresh the layout with the new data. (This happens only once)
The QStyledItemDelegate draws the items on the QListView in iconMode gridview.
Everything is working except the QListView being unresponsive, lagging, flicks and won't allow me to scroll for a long time.
The messages i get in the console are:
QBuffer::seek: Invalid pos: -345244657
QBuffer::seek: Invalid pos: -345244657

- multiple times everytime i move my mouse in the QListView.
I did some research before writing this, but couldn't find anything useful.
I suspect this being the main reason on why the QListView is so unresponsive, and i think it's something related to the QIcon i make.
However i did some profiling and saw that the paint method in the Delegate got called over 200 times in an elapsed time of 1 minute without me touching the mouse.

My code:
http://pastebin.com/gjKJwJuU

Things to note:
I use PyQt5 but can understand slight C++ code.
Pseudo code will only be useful for me if you include the methods being called.

Edit #1:
I just realized that with the fetchMore method, I don't need to emit layoutChanged so i removed that.
I also moved the endResetModel() call up to the append method, because that's when items are actually added into the model.
This changed nothing. ListView is still being unresposive/lagging. I also tried only adding 3-5 items to the list still getting same results...

Edit #2:
Okay so i stopped the paint method in the delegate from painting the images, which seems to have fixed the laggy QListView...
I also stopped getting the QBuffer::seek invalid pos: -xxxxxx messages.
So now i have another question.
How do i fix the lagging in the QListView when painting images?

I'm changing the title to this question instead of: QBuffer::seek invalid pos: -xxxxxx.

wysota
4th May 2015, 20:09
In my opinion your thread does totally nothing.

The following code:

data_thread.started.connect(fetch_instance.local)

will cause fetch_instance.local to be called in the main thread and not the worker thread. Whatever you do in this function will make the UI unresponsive.

anda_skoa
4th May 2015, 21:39
The signal invokes layoutChanged() (don't know how to use dataChanged anywhere except in the obligatory data method), which will then refresh the layout with the new data.

If you add data, why not use beginInsertRows() endInsertRows()?

Cheers,
_

isplasher
5th May 2015, 13:45
In my opinion your thread does totally nothing.

The following code:

data_thread.started.connect(fetch_instance.local)

will cause fetch_instance.local to be called in the main thread and not the worker thread. Whatever you do in this function will make the UI unresponsive.

Hello, thank you for answering.
The thread is working. You can see that i move the fetch_instance to the thread just above that code. I can also confirm this, because when i start the process, i can still move the GUI around, and everything is okay.


If you add data, why not use beginInsertRows() endInsertRows()?

Cheers,
_

I actually just tried this, and the issue still remains.
I tried adding the two calls in the append method in my code.

isplasher
5th May 2015, 18:31
I just made a new discovery!
While surfing on the net I stumbled upon QPixmapCache. While thinking it was the solution to my issue, i set it up.
Unfortunately the issue still remains, but i discovered a symptom.
To be sure i setup the caching correctly i made it print "from cache", "new image" depending on if the image was fetched from the cache, or was created anew.
This showed some interesting results. On start it printed "new image" about 15 times as expected. I Expected 15 times because i set the limit in the fetchMore
method to 15.
Then i try moving the mouse inside the ListView, without scrolling, just moving the mouse around abit. This made the console go wild with alot of mixed messages of
"from cache" and "new image", which about 60-70% of the messages were "new image". With this i think i finally narrowed down the cause of why the gui is lagging.
It suggests that somehow the view is not only painting the needed (visible) images, but everything when you move your mouse inside the view.
This however hasn't solved my problem, so please don't think that i still don't need help. I just wanted to give an update on what i have found.

wysota
5th May 2015, 18:36
What happens if you increase the size of the pixmap cache?

isplasher
5th May 2015, 18:42
What happens if you increase the size of the pixmap cache?

Wow, so i just multipled the cache with 1000 (10240*1000) and it helped alot.
The gui was still lagging but not as much as before.

wysota
5th May 2015, 18:50
Wow, so i just multipled the cache with 1000 (10240*1000) and it helped alot.
The gui was still lagging but not as much as before.

The effect you observed before was caused by cache flickering. How large are your images? Isn't the lagging caused by scaling pixmaps?

isplasher
5th May 2015, 18:58
The effect you observed before was caused by cache flickering. How large are your images? Isn't the lagging caused by scaling pixmaps?

Oh i see.. I completely forgot about the image size.
The images i use mostly have the dimensions 1500x2100px. They are about 2mb each.
After reading that i now realize why all this was happening.. (facepalms)
Anyway, yes, i think you're right about the pixmap scaling. Do you have any solutions, other than using smaller images?

wysota
5th May 2015, 19:23
Scale them once before adding them to your model and use the thumbnail instead of the original image.

isplasher
5th May 2015, 19:29
Right.
Was thinking of the same approach.
Thank you for your help, kind sir. :)