1
  • Take a form
  • Place two CommandLinkButton(s) on the form
  • Place a PushButton on the form
  • Right click PushButton-> Go to slot...
  • Choose clicked()
  • Write following code:
std::cout << ui->commandLinkButton->icon().cacheKey() << std::endl;
std::cout << ui->commandLinkButton_2->icon().cacheKey() << std::endl;

Why does that code print two different values for the cachekey? We did not change the icon of any CommandLinkButton so both have the same default icon!

My problem is like this: I have a push button with an icon on it, which is coming from resources. I want to verify in test code that it has the same required icon on it.

To do that I compare the cachekey of image on the push button and cachekey of QPixmap object having same image like this:

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

But that test fails because cacheKey turns out to be different. So what is the best way to do that check? Basically like calculating hash of image and match that hash, which should always be same for any instance of same image.

Sumit
  • 1,485
  • 11
  • 24

1 Answers1

2

That's because two icons are not cached in the same cache and/or not copied from the same object. Look at item 2 of this answer and cacheKey documentation.

To get the same cacheKey for different icons you should create an icon object in constructor of your window and call setIcon on it for both CommandLinkButtons.

Update: To compare the icon with a bitmap from file by hash, you need some data-based hashing. Fortunately, Qt provides a bunch of qHash functions and qHashBits function for continuous memory blocks. You may compare your images hashes like this:

// 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) {.......}

Here we get image raw data in a very clumsy and unnatural way and then compute hashes of it. It's probably not what you want. Hashes returned by qHashBits are not the values returned by cacheKey. Furthermore, these hashes may differ as image is loaded directly from file, while QIcon may perform some processing on it's image during construction. qHashBits comes from Qt's hash table implementation, so it implies that minor changes of input data yield significant changes of returned hash. To compensate possible difference, you may construct QIcon object from image with options same as in the interface, and then obtain icon's data.

And it's not clear from your example, what for to take hashes before comparison? Hashing requires whole data traversal, so it will not be faster that just std::equals on data until you compare thousands of images to one image.

Community
  • 1
  • 1
Sergey
  • 7,985
  • 4
  • 48
  • 80
  • Added more details about my problem, could you please help in that particular scenario. – Sumit Jul 14 '16 at 04:47