1

I have a problem putting a GUI in a class. Loading an image from a file, resize and display it on a canvas works as long the complete code runs in main(). In the code below I do the same steps in a class. The image is shown, but entering the mainloop() the canvas is cleared.

Many thanks

import tkinter as tk
from PIL import Image, ImageTk
import time

class Gui():
    
    def __init__(self, window):       
        File = "/home/pi/Rainer/Graphic/Bahn01.png"
        img = self.load_image(File, 0.5)
       
        canvas = tk.Canvas(window, bg='white')
        canvas.place(x=10, y=10, width=300, height=400)
        canvas.create_image(0, 0, image=img, anchor="nw")
        window.update()

    def load_image(self, File, Zoom):
        img = Image.open(File)
        resized_image = img.resize((int(600 * Zoom), int(800 * Zoom)), Image.Resampling.LANCZOS)
        return ImageTk.PhotoImage(resized_image)

def main():  
    
    root = tk.Tk()
    root.geometry("620x420+320+20")
        
    App = Gui(root)
    
    time.sleep(3)

    root.mainloop()


if __name__ == '__main__':
    main()

1 Answers1

1

The issue you're facing is because the img variable in your Gui class is a local variable within the __init__ method. When the method finishes executing, the ``img variable is no longer referenced and gets garbage-collected. This causes the image to disappear from the canvas.

To fix this, you need to store the image as an instance variable of the Gui class. You can do this by using the self keyword.

Here's an updated version of your code:

import tkinter as tk
from PIL import Image, ImageTk
import time

class Gui():
    
    def __init__(self, window):       
        File = "/home/pi/Rainer/Graphic/Bahn01.png"
        self.img = self.load_image(File, 0.5)
       
        self.canvas = tk.Canvas(window, bg='white')
        self.canvas.place(x=10, y=10, width=300, height=400)
        self.canvas.create_image(0, 0, image=self.img, anchor="nw")
        window.update()

    def load_image(self, File, Zoom):
        img = Image.open(File)
        resized_image = img.resize((int(600 * Zoom), int(800 * Zoom)), Image.Resampling.LANCZOS)
        return ImageTk.PhotoImage(resized_image)

def main():  
    root = tk.Tk()
    root.geometry("620x420+320+20")
        
    App = Gui(root)
    
    time.sleep(3)

    root.mainloop()


if __name__ == '__main__':
    main()

You can see this answer for more help.

codester_09
  • 5,622
  • 2
  • 5
  • 27