[Question] Add image inside sg.Table()?
UpstreamData opened this issue · comments
Type of Issue (Enhancement, Error, Bug, Question)
Question
Operating System - Windows 10
PySimpleGUI Port - tkinter
Versions
Version information can be obtained by calling sg.main_get_debug_data()
Or you can print each version shown in ()
Python version - 3.10.0
PySimpleGUI Version - 4.53.0
GUI Version - tkinter 8.6.10
Your Experience In Months or Years (optional)
Years Python programming experience - 2
Years Programming experience overall - 2
Have used another Python GUI Framework? - No
Anything else you think would be helpful?
Troubleshooting
These items may solve your problem. Please check those you've done by changing - [ ] to - [X]
- Searched main docs for your problem www.PySimpleGUI.org
- Looked for Demo Programs that are similar to your goal Demos.PySimpleGUI.org
- If not tkinter - looked for Demo Programs for specific port
- For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
- Run your program outside of your debugger (from a command line)
- Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
- Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed but not released
Detailed Description
I am creating a program that deals with external devices, and as part of that logs them and some information about them in a sg.Table. With these devices, I have the ability to turn on or off an LED on the device, and to indicate that, I am configuring the tags of the table to set rows with the LED on to red. I would prefer a nicer way of doing this that doesn't interfere with other tags (such as coloring the devices based on status), so I was looking into a way to add a LED indicator to each table row.
The LEDs from DemoLEDIndicators.py would be perfect, but to my knowledge, there is no way to insert one element into another (as mentioned here. I also thought about having the LED indicators outside the table, but since the program can be dealing with 100s of devices at once, I would run into an issue as soon as someone needed to scroll through the table.
This leads to my question - Is there any way to insert an image (or possibly a GIF) into a table? If not, is there any better way to handle what I am trying to do?
Oh, and appreciate all the time that has went into this project, PySimpleGUI has been amazing to work with thus far.
Code To Duplicate
Not really any specific code to duplicate, and since the project is so expansive and interwoven to handle these devices, its likely best if I just leave a link to the github page with the project. (the program to run is config_util.py, source for the specific GUI is under tools/cfg_util/cfg_util_sg)
https://github.com/UpstreamData/minerInterface
Screenshot, Sketch, or Drawing
This is the sort of output I would be looking for, although my guess is this isn't possible right now.
Watcha Makin?
For the structure of Table element, there's no way to add image for each row.
Try the Tree element, but maybe something different, like the option enable_click_events
in Table element not found in Tree element.
Example Code
from io import BytesIO
import base64
from PIL import Image
import PySimpleGUI as sg
def size(base64_image):
"""
Return size of image
"""
im = Image.open(BytesIO(base64.b64decode(base64_image)))
width, height = im.size
return f'{width} x {height}'
# Get name and image of all internal EMOJI base64 images
emoji = {
key:value for key, value in sg.__dict__.items()
if key.startswith("EMOJI_") and type(value)==bytes
}
keys = sorted(list(emoji.keys())) # key list of images
dims = [size(emoji[key]) for key in keys] # size list of images
font = ("Courier New", 11)
sg.theme("DarkBlue3")
sg.set_options(font=font)
treedata = sg.TreeData()
for key, (text, value) in enumerate(zip(keys, dims)):
treedata.insert("", key, text, [value], icon=emoji[text])
col0_width = max(map(len, keys))+5
layout = [
[sg.Tree(data=treedata, headings=['Image Size'], col0_width=col0_width,
key='-TABLE-', row_height=64, auto_size_columns=False, col_widths=[12],
num_rows=3, col0_heading='Image')],
]
window = sg.Window('Title', layout, finalize=True)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
window.close()
Appreciate the quick response. I will look into this and see if it will works in this situation, although I need to be able to select rows in the table, so this may not work just based off of the image you attached.
Quick tests indicate this might work well, I will do some more extensive testing.
It is a bit weird to me that this isn't something that can be done with a sg.Table, but can be done with a sg.Tree, since they both appear to originate from a Treeview in tkinter. Is this something that might be added in the future, or is this something that has been deliberately separated?
I've also noticed in research that tags in tkinter appear to have some sort of image functionality, and since I'm already using tags to style the rows, I wonder if this might be a viable solution. I have no idea how to implement this, so I will keep looking, but if you have any suggestions it would be greatly appreciated.
Overall I'm going to try to exhaust all my simple options first, as I would rather not overhaul a large part of my data gathering and UI code for something as (admittedly) trivial as a picture of an LED.
For value of option show
in tk.Treeview
, a string containing zero or more of the following values, specifying which elements of the tree to display.
- 'tree' - Display tree labels in column #0.
- 'headings' - Display the heading row.
The default is 'tree headings', i.e., show all elements. Column #0 always refers to the tree column
In PySimpleGUI, two modes used for tk.Treeview
- 'headings' for Table element
- 'tree headings' for Tree element
These two elements work maybe something different, that's why they maybe with different options or different methods provided till now.
There's tag functionality for tk.Treeview.
The following options may be specified on tags:
- foreground, specifies the text foreground color.
- background, specifies the cell or item background color.
- font, specifies the font to use when drawing text.
- image, specifies the item image, in case the item's -image option is empty.
Tag priority is decided by the creation order: tags created first receive higher priority.
There's no tag method provided in PySimpleGUI elements, you need to call tkinter methods directly by yourself.
I have been calling the tk.Treeview tags through the Widget of the sg.Table, and it appears to be working, I'm just not completely sure about showing images in it, and although the image tag appears to work, it doesn't do anything.
I have no concern about calling methods directly from tkinter, I'm just not exactly sure what I should be calling. Do you know of a way to set the Table into "tree headings" mode and retain functionality of the table (such as the way it is updated)?
I'll take a look into the tkinter docs for the show
method and see if I can figure it out. Appreciate the direction.
You can call method configure
to widget of Table element, like
element.Widget.configure(show="tree headings")
but all the methods exist for Table element not handle the column #0
, you may need to handle everything by tkinter, including the values
which returned by method read
.
I think I'm going to close this now, my question has definitely been sufficiently answered. I would love to see images inside a table (assign an image to any index, not just 0) as a future feature, but now that I understand a bit more about how the tkinter base for the tables work, I feel like this might not be possible due to the limitations of the framework.
i need your support to send me code python by my email basanharki1979@gmail.com
It should be better to post you question and script on a new issue, maybe also the picture to show your requirements.