QIcon::pixmap(size)返回尺寸异常的可行 workaround 方案咨询
问题根因
这个问题是已确认的Qt已知Bug(对应编号QTBUG-95999),触发场景为Windows平台下通过QFileIconProvider获取带Shell扩展覆盖图标的资源(含Git仓库带状态标记的文件夹、Windows快捷方式.lnk文件等)时,QIcon的availableSizes可以正确枚举到原始图标的所有可用尺寸,但调用pixmap接口时,Qt内部逻辑错误地优先匹配覆盖层图标的最大可用尺寸(通常为32x32),导致返回的图标被强制缩小。
可用临时解决方案
下面给出两个经过实测有效的临时修复方案:
方案1:Qt接口层面绕过,显式指定设备像素比调用
QIcon的pixmap有一个带devicePixelRatio参数的重载接口,显式传入当前屏幕的设备像素比可以绕过默认逻辑的尺寸匹配错误,修改测试代码中pixmap获取部分即可:
// 原错误写法 // QPixmap pixmap = icon.pixmap(QSize(256, 256)); // 修复后的写法,显式传入设备像素比 qreal dpr = image.devicePixelRatioF(); QPixmap pixmap = icon.pixmap(QSize(256, 256), dpr); // 如果不需要适配高DPI,直接传1.0也可以 // QPixmap pixmap = icon.pixmap(QSize(256, 256), 1.0);
该方案改动最小,无需调用平台原生API,跨Qt版本兼容性较好。
方案2:Windows原生API获取(适合需要更稳定图标的场景)
如果方案1在部分极端场景下仍然失效,可以直接调用Windows Shell API获取指定尺寸的文件图标,避开QFileIconProvider的问题逻辑:
#include <windows.h> #include <shellapi.h> QPixmap getWindowsLargeIcon(const QString& filePath, int size) { SHFILEINFOW sfi; ZeroMemory(&sfi, sizeof(sfi)); // 先获取图标句柄 SHGetFileInfoW((LPCWSTR)filePath.utf16(), 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_LARGEICON); if (!sfi.hIcon) return {}; // 将HICON转为QPixmap QPixmap pixmap = QPixmap::fromHICON(sfi.hIcon); // 销毁图标句柄避免资源泄漏 DestroyIcon(sfi.hIcon); // 按需缩放到目标尺寸 if (pixmap.size() != QSize(size, size)) { pixmap = pixmap.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation); } return pixmap; }
注意该方案仅限Windows平台使用。
内容的提问来源于stack exchange,提问作者HiFile.app - best file manager
相关产品推荐
相关产品推荐

