I am making a program that displays a calendar picture in tkinter.

import tkinter as tk
from tkinter import PhotoImage
w0 = tk.Tk ()
img0 = tk.PhotoImage (file ='calendar.png', master = w0)
img0 = img0.subsample (5)
w1 = tk.Toplevel ()
def button_push ():
    img1 = tk.PhotoImage (file ='calendar.png', master = w1)
    img1 = img1.subsample (5)
    b1 = tk.Button (w1, image = img1)
    b1.place (x = 5, y = 5)
b0 = tk.Button (w0, image = img0, command = button_push)
b0.place (x = 5, y = 5)

So, even if I do it, the picture is not displayed when the button is pressed. .. ..
I don't get any error message. .. ..
(Only the frame is displayed)

  • Answer # 1

    Cause: The variable containing the PhotoImage object
    Because it is a local variable in the button_push function
    When the function finishes executing, the PhotoImage image is discarded.

    Details: Tkinter's non-Widget objects (Variable and PhotoImage)
    Since the lifetime is different from widgets etc., you need to manage it independently.

    For a normal Python object, use tk.Button (w1, image = img1)
    I'm hoping that the Button will have a reference to img1
    Inside the Button, you're just passing the ID string (usually the filename) based on img1
    The widget does not hold the object itself passed to the image.


    Make it a global variable.
    In the case of this code, if you want to display the same image, you don't need to generate a new img1.image = img0But it's okay.

    Make PhotoImage an instance variable using a class.

    Save to the attribute of a long-lived object (usually a global variable) somewhere

    Since we are using Toplevel, if you want to create a dialog,
    It's a good idea to create a class of dialogs and have a PhotoImage object in its instance variable.