Вчера обнаружил странное поведение QDirModel/QFileSystemModel.
Вот как отображаются маленькие иконки при первом просмотре файлов с таким типом - см. аттач #1
И вот как после изменения порядка сортировки - см. аттач #2
Похоже на то, что у файла определенного типа, для которого еще не получена иконка - показывается нормальная small иконка.
Для всех последующих файлов того же типа - уже large иконка, уменьшенная до размеров строки.
Начал копаться в коде, и похоже нашел вот какой баг в QFileIconProvider.cpp:
QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
...
QPixmap pixmap;
QPixmapCache::find(key, pixmap);
if (!pixmap.isNull()) {
retIcon.addPixmap(pixmap);
if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
retIcon.addPixmap(pixmap);
return retIcon;
}
...
//Get the small icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
if (val) {
pixmap = convertHIconToPixmap(info.hIcon);
if (!pixmap.isNull()) {
retIcon.addPixmap(pixmap);
if (!key.isEmpty())
QPixmapCache::insert(key, pixmap);
}
DestroyIcon(info.hIcon);
}
...
//Get the big icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
if (val) {
pixmap = convertHIconToPixmap(info.hIcon);
if (!pixmap.isNull()) {
retIcon.addPixmap(pixmap);
if (!key.isEmpty())
QPixmapCache::insert(key, pixmap);
}
DestroyIcon(info.hIcon);
}
Я не силен в цпп, но похоже на то, что сначала идет запрос к кешу по ключу key. Ничего там не найдя, происходит получение small иконки, которая добавляется как pixmap в retIcon и сам pixmap пихается в кеш. Дальше, тоже самое делается для large иконки, при этом заменяя в кеше pixmap на новый, большой. И возвращается retIcon, из которой берется (видимо) первый добавленный pixmap.
А вот при повторном запросе на иконку файла с типом, для которого иконка уже есть в кеше, возвращается сразу же та, которую туда последнюю положили, т.е. large.
Кто может, проверьте пожалуйста, такое ли и у вас поведение. Можно просто запусить examples\itemviews\dirview.
Версия Qt 4.4.3.
Я попробовал просто удалить ту часть кода, которая получает large иконку и перекомплил либу - и иконки стали нормальными. По-крайней мере, маленькие.
Имхо, в функу getWinIcon нужно добавить параметр, в котором можно указывать, какого размера иконка нужна. И соответственно, все юзающие его классы переписывать. Но это уже к тролям.