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.
https://www.PySimpleGUI.com
Other
13.36k stars 1.84k forks source link

[Bug] Hitting the image-count limit [Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize] #6743

Closed Walter-o closed 5 months ago

Walter-o commented 5 months ago

Type of Issue (Enhancement, Error, Bug, Question)

Bug


Operating System

Windows

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

port: tkinter tkinter version: 8.6.12 PySimpleGUI version: 4.60.5 PySimpleGUI filename: C:\Users...\venv\lib\site-packages\PySimpleGUI\PySimpleGUI.py

Python version (sg.sys.version)

Python version: 3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)]

PySimpleGUI Version (sg.__version__)

4.60.5

GUI Version (tkinter (sg.tclversion_detailed), PySide2, WxPython, Remi)

tkinter


Years Python programming experience: 999

Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine) I have tested this bug on the Qt port however it seems to hang indefinitely at roughly 50.000 images

Anything else you think would be helpful? There is 32GB ram in this PC and OS arch is 64bit


Troubleshooting

These items may solve your problem. Please check those you've done by changing - [ ] to - [X]

Detailed Description

I have a feature in a program that would at most load around 100.000-200.000 images of size 150x150. However, PySimpleGUI's tkinter port seems to crash at roughly 4990 image objects (this is without the actual image data already).

I think it's a memory overflow issue, since i get a variety of different error messages in the range of 4990-5000 objects. In the github issues page i could not find anyone with the same problem

The first hit on Google for the error: "Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize" Does have a result, but the recommended fix is to update matplotlib... something that neither PySimpleGUI or my project use.

Hopefully there is some value deep in tkinter that can bump the memory allocation up a bit so i can keep making cursed things LOL.

Code To Replicate

import PySimpleGUI as sg

class Replication:
    def __init__(self):
        layout = [[sg.Image(size=(50, 50), visible=False) for x in range(200000)]]
        self.window = sg.Window(layout=layout,
                                title="Image limit bug replication",
                                size=(300, 300))

    def run(self):
        while True:
            self.event, self.values = self.window.read()
            if self.event == sg.WINDOW_CLOSED:
                break
        self.window.close()

Replication().run()

or

import PySimpleGUI as sg
layout = [[sg.Image(visible=False) for x in range(200000)]]
window = sg.Window(layout=layout, title="")
window.read()

Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize

Screenshot, Sketch, or Drawing


Watcha Makin?

Just some grid that shows which medals certain accounts have obtained in a game. image

Walter-o commented 5 months ago

I just verified that 200.000 text elements work without a problem (albeit a bit slow to load)

That makes it even more weird that it crashes before even 5000 empty image elements.

Also this means i can pivot to using ✅ and ❎ as emoji's in text in the meantime.

Walter-o commented 5 months ago

Alright, i worked around the bug but i'm still leaving the issue open since i'm curious if there is a fix, i might run into it in the future. image

PySimpleGUI commented 5 months ago

This is a tkinter-based error, not a PySimpleGUI one. It would be helpful to write a small example using tkinter and report it to that team. I certainly am not going to know about any values deep in tkinter.

Rather than brute force creating so much at one time in RAM, can you think of a bit more sophisticated design that can get around this (perhaps reasonable) limitation? You can't show 200,000 images all at the same time, so some kind of buffering, paging, etc, scheme should be possible.

Walter-o commented 5 months ago

Hey!

I think you are right about it being a good idea to add pagination. Maybe baking the stuff in an image with pillow is an option too, but i also have tooltips on every item.

In the future i could make a fake scrollbar on 1 axis that loads and deloads stuff.

Also i tested out if tkinter breaks at high image counts and the breaking point is really similar, it's a tiny bit higher on tkinter alone. And PySimpleGUI with 200.000 text objects still breaks if it's mixed in with columns and similar.

So it looks like it's just a general memory limit issue in tkinter where the image objects take a ton of space compared to other types.

I'm going to experiment further and might report my issues to tkinter/wx/Qt etc if i get around to it.

But anyways thanks for the response!

PySimpleGUI commented 5 months ago

thanks for the response!

Sure! That's why we're here. image Thank you for the "thanks"!

Jason's posted several examples of various ways of implementing loading of assets as needed rather than creating them in advance in response to user's issues over the years. You should be able to locate some by searching the issue database (assuming you can craft a search that returns a reasonable number of hits).

jason990420 commented 5 months ago

Maybe you can refer issue #3787