Qt list of images

3.2k views Asked by At

I am looking for an efficient way to view a list of thumbnails of jpegs in Qt 5.8 (possibly several thousands).

My current approach is to use a QListWidget (see below, and this question). This turns out to be way too slow as it takes forever to assemble, even for a few images.

I am looking:

  1. To understand why my current approach is so slow.
  2. For a more efficient approach, which still requires only little code by relying as much as possible on Qt's features.

Current approach:

ui->listWidget->setViewMode  (QListWidget::IconMode);
ui->listWidget->setIconSize  (QSize(200,200)       );
ui->listWidget->setResizeMode(QListWidget::Adjust  );

for ( auto &i : files ) 
  ui->listWidget->addItem(new QListWidgetItem(QIcon(i),i));

(whereby files is of the std::vector<QString> type)

2

There are 2 answers

0
G.M. On BEST ANSWER

A quick solution might be to create a simple class that inherits from QListWidgetItem and fixes up the thumbnails on demand. You could try something like (note: untested)...

class thumbnail_item: public QListWidgetItem {
  using super = QListWidgetItem;
public:
  explicit thumbnail_item (const QString &filename)
    : super(filename)
    {}
  virtual QVariant data (int role) const override
    {
      if (role == Qt::DecorationRole) {
        QIcon i = super::icon();
        if (i.isNull()) {

          /*
           * The existing thumbnail (if any) is empty so create one
           * from the file name and use it -- remembering to call
           * setIcon so we don't need to go through all this again
           * next time.
           */
          i = QIcon(data(Qt::DisplayRole));
          setIcon(i);
        }
        return(i);
      }
      return(super::data(role));
    }
};

You still need the loop to create an item for each file but at least it defers the thumbnail construction.

A more elegant solution would probably involve using fully separated model and view objects with a custom proxy model performing the thumbnail generation and caching.

0
TimeS On

I have low rep to comment on G.M.'s answer, so here is my addition:

The initialisation may take long time due to 2 reasons:

  1. The access to image files and their decoding can take up significant time. It is nice to have some buffering/precaching or defering, as G.M. suggested.
  2. I believe, images are loaded "as is" (in high resolution), but resized to tiny resolution for thumbnail view inside QIcon. This can be optimised away by using QImageReader class for image reading, specifically its method setScaledSize(const QSize &size).