0

I've been working with Tkinter to create new windows through button clicks. Recently I've been trying to size the buttons in order to fit the screen. I tried using the trick that uses a 1 by a 1-pixel image so I can size the buttons but pixels. I've noticed whenever I try to put the image on the button no longer works. If I comment out the image parameter the button starts to work. I have no clue why. Heres the code:

import tkinter as tk
import module1
class win1:
    def __init__(self,master):
        self.master = master
        self.master.geometry("400x400")
        self.frame=tk.Frame(self.master)
        #self.butnew("Hi there","2",win2)


        #####################           FullScreen           ###################
        w, h = master.winfo_screenwidth(), master.winfo_screenheight()
        self.master.overrideredirect(1)
        self.master.geometry("%dx%d+0+0" % (w, h))
        self.master.focus_set() # <-- move focus to this widget
        self.master.bind("<Escape>", lambda e: e.widget.quit())#Quits when escape is pressed

        for i in range(3):
            self.master.columnconfigure(i, weight=1, minsize=75)
            self.master.rowconfigure(i, weight=1, minsize=50)

            for j in range(0, 3):
                self.butnew("ji","g",module1.stonky,i,j)
        self.frame.pack()

    def butnew(self,text,number,_class,i,j):
        sizeWidth = int(self.master.winfo_screenwidth()/81)
        sizeHeight = int(self.master.winfo_screenheight()/81)
        pixel = tk.PhotoImage(width=sizeWidth, height=sizeWidth)
        tk.Button(self.frame,
                  text = text,
                  image=pixel,#If i comment out this line it works
                  #width=sizeWidth,
                  #height=sizeHeight,
                  compound="center",
                  command= lambda: self.new_window(number,_class)).grid(row=i,
                                                                        column=j,
                                                                        padx =3,
                                                                        pady=4)

    def new_window(self,number,_class):
        self.new = tk.Toplevel(self.master)
        _class(self.new,number)




root = tk.Tk()
app = win1(root)
root.mainloop()
  • Possible dupe of https://stackoverflow.com/questions/3359717/cannot-display-an-image-in-tkinter – 10 Rep May 29 '20 at 05:46

1 Answers1

1

It is because the image is garbage collected as it is created inside a function. You need to keep a reference to the image:

def butnew(self,text,number,_class,i,j):
    sizeWidth = int(self.master.winfo_screenwidth()/81)
    sizeHeight = int(self.master.winfo_screenheight()/81)
    pixel = tk.PhotoImage(width=sizeWidth, height=sizeWidth)
    btn = tk.Button(self.frame,
                    text=text,
                    image=pixel,
                    #width=sizeWidth,
                    #height=sizeHeight,
                    compound="center",
                    command=lambda: self.new_window(number,_class))
    btn.grid(row=i, column=j, padx =3, pady=4)
    btn.photo = pixel # keep a reference to the image
acw1668
  • 40,144
  • 5
  • 22
  • 34