PDA

View Full Version : QFileIconProvider custom icon slow



smiffsh
24th October 2023, 20:45
I'm using a QFileIconProvider class to show image thumbnails in a QFileDialog by overriding the 'icon' method to load from a file to a QIcon.

After implementing this, the file dialog is very slow in navigating through sub-folders and hangs for a few seconds before changing directory.

C++ class is below.

Why is the rendering being slow and how can I speed it up?



QIcon CFileIconProvider::icon(const QFileInfo &info) const
{
const QString &path = info.absoluteFilePath();

// check if 'info' is a drive type
if (path.isEmpty())
return QFileIconProvider::icon(QFileIconProvider::Drive);

if (info.isFile()) {
if (QFile(info.absoluteFilePath()).exists()) {
// show file as icon
QImage originalImage(info.absoluteFilePath());

if (!originalImage.isNull())
return QIcon(info.absoluteFilePath());
}
}

// check if 'info' is a directory type
if (info.isDir())
return QFileIconProvider::icon(QFileIconProvider::Folder) ;

return QIcon();
}





#ifndef FILEICON_PROVIDER_H
#define FILEICON_PROVIDER_H

#include <QFileIconProvider>
#include <QObject>
#include <QIcon>

class CFileIconProvider : public QFileIconProvider
{

public:
CFileIconProvider();
QIcon icon(const QFileInfo &info) const override;

};

#endif // FILEICON_PROVIDER_H

Ginsengelf
25th October 2023, 07:01
Hi,
I think in this part


if (info.isFile()) {
if (QFile(info.absoluteFilePath()).exists()) {
// show file as icon
QImage originalImage(info.absoluteFilePath());

if (!originalImage.isNull())
return QIcon(info.absoluteFilePath());
}
}
you read the file two times, once to create the QImage, and then again to create the QIcon for the return.
It would also probably help to cache the created icons so that you only have to create them once.

Ginsengelf

smiffsh
7th February 2024, 22:53
Thanks Ginsengelf,

You were right the method was rending the file twice in the loop, which also was taking a lot of time to load into a QIcon.

As per suggestion, I created a cache of icons that were rendered in a seperate thread in order to not be blocking, hash map was defined via:


QMap<QString, QIcon>* iconCache;