-2

Today i was Trying to Display All .png files in my current Directory In a GUI With Python and Tkinter but The Code Was Not Wroking in a Way That i expected It only Displays The Last Image of the Folder and The Space for Other Images Was Blank.

# Importing Essentials
import os
from tkinter import Tk, Label, PhotoImage

# Initialize Tk root Class
root = Tk()

# Set Default Size of Our Tkinter Window - (WidthxHeight)
root.geometry("200x910")

# Set Minimum Size of Our Window - (Width, Height)
root.minsize(350, 200)

# Add a Label
WelcomeLabel = Label(text="All Images of This Folder")
WelcomeLabel.pack()

# Get All PNG Files in a List name pngFiles
pngFiles = []
for item in os.listdir():
    if item.endswith(".png"):
        pngFiles.append(item)

# Display All The PNG files to our GUI Screen
for file in pngFiles:
    photoLoaded = PhotoImage(file=file)
    mainImageLabel = Label(image=photoLoaded)
    mainImageLabel.pack()

# Run The MainLoop
root.mainloop()
  • 1
    See https://stackoverflow.com/questions/16424091 – Bryan Oakley Jan 21 '23 at 12:55
  • @BryanOakley why isn't this just a duplicate? (Also, why doesn't the `Label` maintain an internal reference to the image and prevent it from being GCd?) – Karl Knechtel Jan 21 '23 at 13:37
  • @KarlKnechtel: It's not an exact duplicate because the question I linked to has to do with creating images in a function. In this case the OP doesn't use a function. However, the root cause is the same: not holding a reference to the image. – Bryan Oakley Jan 21 '23 at 14:36
  • @KarlKnechtel: why doesn't the label maintain an internal reference to the image? I don't know. You would probably have to ask the person who originally wrote the `Label` class. It seems like poor design, but maybe they had a reason. Iikely it's due simply to the fact that tkinter is a think wrapper around an embedded tcl interpreter, and the tcl interpreter knows nothing about python objects. – Bryan Oakley Jan 21 '23 at 14:37

2 Answers2

1

In tkinter the images must have references in memory, you cannot overwrite and reuse them, my solution is to make a list using pathlib, and then create the labels

If you display an image inside a function, then make sure to keep reference to the > image object in your Python program, either by storing it in a global variable or > by attaching it to another object.

Basics For Displaying Image In Tkinter Python

import pathlib
from tkinter import Tk, Label, PhotoImage

root = Tk()
root.geometry("200x910")
root.minsize(350, 200)

wellcome = Label(text="All Images of This Folder")
wellcome.pack()

# create a list from images with memory reference
images_with_ref = []
for img in pathlib.Path('.').glob('*.png'):
    photoLoaded = PhotoImage(file=img)
    images_with_ref.append(photoLoaded)

# create labels with correct images
for image in images_with_ref:
    Label(image=image).pack()

root.mainloop()

Example

Collaxd
  • 425
  • 3
  • 12
0

With the current code you are overwriting your photoLoaded with every loop. Instead you have can pack these photoLoaded in a list. Additionally working with grids is recommended when working with multiple items.

both things are implemented in the code below:

# Importing Essentials
import os
from tkinter import Tk, Label, PhotoImage

# Initialize Tk root Class
root = Tk()

# Set Default Size of Our Tkinter Window - (WidthxHeight)
root.geometry("200x910")

# Set Minimum Size of Our Window - (Width, Height)
root.minsize(350, 200)

# Add a Label
WelcomeLabel = Label(text="All Images of This Folder")
WelcomeLabel.grid(row=0)

# Get All PNG Files in a List name pngFiles
pngFiles = []
for item in os.listdir():
    if item.endswith(".png"):
        pngFiles.append(item)
print(pngFiles)
# Display All The PNG files to our GUI Screen
i = 0
pics = []
for file in pngFiles:
    pics.append(PhotoImage(file=file))
    Label(root, image=pics[i]).grid(row=i + 1)
    i += 1

# Run The MainLoop
root.mainloop()
tetris programming
  • 809
  • 1
  • 2
  • 13