[ Pyside ] Not able to get images to work as ToolTip for QPushButton.

[ Pyside ] Not able to get images to work as ToolTip for QPushButton.

deven.saxenaP7BD5
Enthusiast Enthusiast
2,020 Views
18 Replies
Message 1 of 19

[ Pyside ] Not able to get images to work as ToolTip for QPushButton.

deven.saxenaP7BD5
Enthusiast
Enthusiast

I have a grid of QPushButton that displays an image as their thumbnail icon. This is working correctly and behaves the way that I expect.

The issue is that since the size of the button is small, the image is not very clear(the thumbnail image is 200*200). So in order for the user to see what the thumbnail looks like in detail, I am using the ToolTip option where I am displaying a larger image(1024*1024) for better visibility.

I have a Maya version of the same tool that is working and displays the tooltip image as expected. But for some reason, the tooltip fails to load the image on the max side. It only displays an empty tooltip popup with nothing in it. I have tried replacing the image with a string and that works. It's just that Max fails to load the image when used as a ToolTip. 

 

Heres my code:

self.fullImage = "path\\to\\image.jpg"
self.btn.setToolTip('<img src="{}">'.format(self.fullImage))

 

0 Likes
2,021 Views
18 Replies
Replies (18)
Message 2 of 19

denisT.MaxDoctor
Advisor
Advisor

when you say "fails" does that mean it's throwing some kind of "error message" or just showing nothing?

0 Likes
Message 3 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

Hi Denis, no errors this time. It just shows an empty tooltip without an image. 

0 Likes
Message 4 of 19

denisT.MaxDoctor
Advisor
Advisor

ok... that's what was expected.

Maya's Python framework supports such thing as a 'resource path', so you can point to this path as a directory for your images. Max doesn't support it (or at least I don't know how to do it). 

The only way I know how to add images to ToolTip is using Base64 data format (pseudo-code):

 

img = @"C:\the-path\the-name.png"

pixmap = qui.QPixmap img
buffer = qcore.QBuffer()
buffer.open qcore.QIODevice.WriteOnly
pixmap.save buffer "PNG" quality:100
bim = xpy.builtin.unicode ((buffer.data()).toBase64())
html = xpy.builtin.unicode.format "<img src='data&colon;image/png;base64,{}'>" bim

bt = qwidgets.QPushButton()
bt.setToolTip html
bt.show()

 

I use 'unicode' in my snippet to make it works in MAX 2020... version 2022+ works fine with 'str' 

 

 

0 Likes
Message 5 of 19

denisT.MaxDoctor
Advisor
Advisor

I'm pretty sure there is a shorter way to get Base64. ... something: QFile -> QByteArray -> base64 string... 

0 Likes
Message 6 of 19

denisT.MaxDoctor
Advisor
Advisor

@denisT.MaxDoctor wrote:

I'm pretty sure there is a shorter way to get Base64. ... something: QFile -> QByteArray -> base64 string... 


img = @"C:\the-path\the-name.png"
f = qcore.QFile img
f.open qcore.QIODevice.ReadOnly	
b = (f.readAll()).toBase64()
html = pyformat "<img src='data&colon;image/png;base64,{}'>" b

 

0 Likes
Message 7 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

Hi Denis,

 

Thank you for looking into this. I tied your recommendation and unfortunately, I am not able to get the toolTip to work. 

I looked into the base64 thing and maybe I am not plugin it correctly. Here's what I have in my code. Also, this is in Python.

img = "path/to/image.png"

with open(img, "rb") as image_file:
    image_data = image_file.read()

image_data_base64 = base64.b64encode(image_data)

pixmap = QtGui.QPixmap()
pixmap.loadFromData(base64.b64decode(image_data_base64))
testButton.setToolTip('<b>%s</b><br><img src="%s">' % ("ToolTip", pixmap))

 

0 Likes
Message 8 of 19

denisT.MaxDoctor
Advisor
Advisor

try:

 

img = "path/to/image.png"

with open(img, "rb") as image_file:
    image_data = image_file.read()
image_data_base64 = base64.b64encode(image_data)
testButton.setToolTip('<b>%s</b><br><img src="data: image/png;base64,%s">' % ("ToolTip", image_data_base64))	

 

0 Likes
Message 9 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

I already tried that Denis. It does not work on my end. The code that I shared above was to try and load the image first before plugging it into ToolTip and hence the use of Pixmap. 

Just for sanity, I again tried your code as well, and still no success. Just curious were you able to get this to work on your end by any chance?  

0 Likes
Message 10 of 19

denisT.MaxDoctor
Advisor
Advisor

 

img = @"C:\Program Files\Autodesk\3ds Max 2023\en-US\html\cui.defaults.switcher\_images\max.daylight.png"

io = python.import "io"
base64 = python.import "base64"
blt = python.import "builtins"
f = io.open img "rb"
data = f.read()
b64 = (base64.b64encode data).decode "ascii"

html = blt.str.format "<b>{0}</b><br><img src='data: image/png;base64,{1}'>" "ToolTip" b64

qw = python.import "PySide2.QtWidgets"
bt = qw.QPushButton()
bt.setToolTip html
bt.show()

 

 

try this maxscript...  

0 Likes
Message 11 of 19

denisT.MaxDoctor
Advisor
Advisor

it's MAX 2023 of course

 

0 Likes
Message 12 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

 

 

Awesome that worked. For those who are looking for the python version:

 

import io
import base64
import builtins
img = "path/to/image.png"
f = io.open(img, "rb")
data = f.read()
b64 = base64.b64encode(data).decode("ascii")
html = "<b>{0}</b><br><img src='data: image/png;base64,{1}'>".format("ToolTip", b64)
self.btn.setStyleSheet("QToolTip { width: 1024px; }")
self.btn.setToolTip(html)

 

The overall experience is very disappointing. It's slow since it needs to do the conversion and sometimes fails to load an image before ToolTipDuration kicks in. Is this the only solution available? 

0 Likes
Message 13 of 19

denisT.MaxDoctor
Advisor
Advisor

you can show tooltip when the "html" string is ready.

0 Likes
Message 14 of 19

denisT.MaxDoctor
Advisor
Advisor

@deven.saxenaP7BD5 wrote:

Is this the only solution available? 


another solution is to use the image as background for the tooltip. It can be set with styleSheet:
"QToolTip { background: url(<path/<name>.png); ... }"

 

0 Likes
Message 15 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast
Yes, but for some reason, it fails to load 1024*1024(1MB in size). Even if I disable the tooltip duration. I haven't looked into why that is happening but it looks like it's getting stuck while loading an image and somehow just stalls and shows a sliced version of the image. When I try to load a smaller image 200*200(2Kb) it works better but not the same when we compare it with Maya. It fails to load even that image sometimes and I have to move my mouse to another button and when I hover back, it loads the entire image. But still, a lot better and is workable.

I need to move on to something else for now but I will keep looking into this. Mostly now it's about troubleshooting what impact image size is making and how can we force max to load the entire image and not get a sliced image.

I appreciate you looking into this Denise. Thank you for all your help.
0 Likes
Message 16 of 19

denisT.MaxDoctor
Advisor
Advisor

when I load a large image (2048x2048) as tooltip background, I don't have any side effects. Everything loads pretty fast and shows smoothly.

0 Likes
Message 17 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

Hi Denis,

 

I had some time to look into this. While I managed to get the image to show up, It looks like the width is locked somehow and as a result, it fails to display the entire image. Also fails to wrap text and the width ends before displaying the entire text. I don't know where this width restriction is coming from. Any recommendations?

 

The tooltip text is set following the rich text format and the image is decoded with base64 which we spoke about earlier. 

 

 

0 Likes
Message 18 of 19

denisT.MaxDoctor
Advisor
Advisor

it seems that here we meet with an insurmountable obstacle in the face of #maximum-width of ToolTip. This can be defined at the application (MAX) level and looks as ~200px. My attempts to somehow change this (using, for example, StyleSheet) were unsuccessful. However, everything shows fine using QToolTip and its #showText method.

What type of event to use in this case is up to you ... you can just use the ToolTip event, or you can use MouseButtonPress with RightButton, which looks even more convenient, since it does not involve random occurrence.

0 Likes
Message 19 of 19

deven.saxenaP7BD5
Enthusiast
Enthusiast

Hi Denis,

 

I found an alternative, instead of using a tooltip, I am now launching a dialog upon left click that comprises a label, and that label is connected with my image via pixmap, left click menu items from before have been connected to right click menu items. 

This is better in terms of user experience as well. Tooltip was the straightforward solution, certainly for Maya but for max until we can fix this "cap" issue, I feel this is serving my team's purpose for now. 

Thanks for all your help. 

0 Likes