PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.

Home Page:https://www.PySimpleGUI.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[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.

PySimpleGUILed


Watcha Makin?

https://github.com/UpstreamData/minerInterface ;)

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()

image

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.