在Qt中,为什么同一图标的cacheKey不同

In Qt why cacheKey differs for same icon

本文关键字:图标 cacheKey 不同 Qt 为什么      更新时间:2023-10-16
  • 采用表格
  • 在窗体上放置两个命令链接按钮
  • 在窗体上放置一个按钮
  • 右键单击按钮-> 转到插槽...
  • 选择点击()
  • 编写以下代码:
std::cout << ui->commandLinkButton->icon().cacheKey() << std::endl;
std::cout << ui->commandLinkButton_2->icon().cacheKey() << std::endl;

为什么该代码为缓存键打印两个不同的值?我们没有更改任何命令链接按钮的图标,因此两者都具有相同的默认图标!

我的问题是这样的:我有一个带有图标的按钮,它来自资源。我想在测试代码中验证它是否具有相同的必需图标。

为此,我比较按钮上图像的缓存键和具有相同图像的 QPixmap 对象的缓存键,如下所示:

const QPixmap image(":/MyProject/Images/Yellow_Icon_40x40.png");
if(image.cacheKey() == ui->PushButton->icon().cacheKey()) 
{
    cout<<"OK";
}

但是该测试失败了,因为cacheKey结果是不同的。那么进行检查的最佳方法是什么?基本上就像计算图像的哈希并匹配该哈希一样,对于同一图像的任何实例,该哈希值应始终相同。

这是因为两个图标没有缓存在同一缓存中和/或不是从同一对象复制的。查看此答案的第 2 项和缓存密钥文档。

要为不同的图标获取相同的 cacheKey,您应该在窗口的构造函数中创建一个 icon 对象,并为两个 CommandLinkButton 调用setIcon

更新:若要逐个哈希将图标与文件中的位图进行比较,需要一些基于数据的哈希。幸运的是,Qt提供了一堆qHash函数和qHashBits函数用于连续内存块。您可以像这样比较您的图像哈希:

// assume image and icon object are declared as in your question
QImage imImage = image.toImage();
QImage imIcon = ui->PushButton->icon().pixmap(QSize(1024,1024)).toImage();
auto hbImage = qHashBits(imImage.constBits(), imImage.byteCount());
auto hbIcon = qHashBits(imIcon.constBits(), imIcon.byteCount());
if(hbImage == hbIcon) {.......}

在这里,我们以一种非常笨拙和不自然的方式获取图像原始数据,然后计算它的哈希值。这可能不是你想要的。qHashBits 返回的哈希不是 cacheKey 返回的值。此外,这些哈希可能会有所不同,因为image直接从文件加载,而QIcon可能会在构造过程中对其图像执行一些处理。 qHashBits来自Qt的哈希表实现,因此这意味着输入数据的微小变化会产生返回哈希的显着变化。为了补偿可能的差异,您可以使用与界面中相同的选项从image构造QIcon对象,然后获取图标的数据。

从您的示例中不清楚,在比较之前获取哈希值是为了什么?哈希需要整个数据遍历,因此在将数千个图像与一个图像进行比较之前,仅std::equals数据不会更快。