Important: Please read the Qt Code of Conduct -

QListWidget slow with 25 QPixmap objects

  • Hi,

    I am generating a scrubbable Gallery with PyQt, for some reason, if my view has more than 25 QLabels, that hold QPixmap Images and some other QLabel Objects, my scrolling gets laggy. I think it has to do with the rendering of those 25 Images. When I remove the QtGui.QListView.IconMode the scrolling appears natural.

    alt text

    Any suggestions? I kinda have the feeling that in CPP QT this wasn't an issue.

  • are you calling setItemWidget with a QLabel for every cell?!
    This is madness

    Use a custom QStyledItemDelegate. reimplement the paint event to paint the pixmap in the option.rect

  • ashamed U got me, I am using setItemWidgets. I will have a look at your suggestion, meanwhile, if u have any sources of example that would be great. (and i like your gif)

  • Sorry for the C++ but I don't know python:

    #include <QStyledItemDelegate>
    #include <QGuiApplication>
    #include <QPainter>
    class FullSizeIconDelegate : public QStyledItemDelegate{
        explicit FullSizeIconDelegate(QObject* parent=Q_NULLPTR)
        virtual void QStyledItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{

    then call tableWidget->setItemDelegate(new FullSizeIconDelegate(this)); and just set the images QPixmaps in the decoration role of the widget. For example: tableWidget->model()->setData(tableWidget->model()->index(0,0),QPixmap("myImage.png"),Qt::DecorationRole);

  • Ok, coming back to my problem, I've basically created a new QStyledItemDelegate and populated it with dummy data, but the speed didn't change at all.

    from PyQt4 import QtGui, QtCore
    from PyQt4.QtGui import QStyledItemDelegate, QPixmap
    from PyQt4.QtCore import Qt, QDir
    class ThumbnailDelegate(QtGui.QStyledItemDelegate):
        def __init__(self, parent = None):
            QtGui.QStyledItemDelegate.__init__(self, parent)
        def paint(self, painter, option, index):
            QStyledItemDelegate.paint(self, painter, option, index)
            pixmap = QPixmap("../resources/images/assetBrowser.jpg")
            painter.drawPixmap(option.rect, pixmap)

    and i am calling this as follows:

                self.model().setData(self.model().index(0, 0), QPixmap("../resources/images/upArrow.png"), Qt.DecorationRole)

    So, before i was calling setItemWidget, now setItemDelegate... am i doing something wrong? And i still don't get why this would be faster than "setItemWidget"

  • Lifetime Qt Champion


    You're loading a full size jpeg file on each paint event, that's not the most efficient. You should cache it or at least keep the image in memory.

  • Lifetime Qt Champion

    @Schiho To add to @SGaist : you could calculate thumbnail versions of the jpeg images and use these (you can store them in application data directory as cache).

  • Hi guys, those are tiny pictures (200x160) and I am only loading (at most) 50 of them at once. I am more confused about the fact, that once it's loaded it is slow. I would kinda expect, that the loading process might take a little while, but after that the scrolling gets laggy.

    @jsulm any ideas how to approach that, u aren't talking about pickles, are you?


  • Lifetime Qt Champion

    @Schiho Here is an older blog:
    But you pictures are already small.
    As @SGaist said you're reading image files on each paint event:

    def paint(self, painter, option, index):
            QStyledItemDelegate.paint(self, painter, option, index)
            pixmap = QPixmap("../resources/images/assetBrowser.jpg") # Here you're reading from file
            painter.drawPixmap(option.rect, pixmap)

    You should read them once and keep in memory.

Log in to reply