Matt
Matt

Reputation: 1812

Widgets Not Removed By Grid_forget()

Working off of the Minimal App from the Tkinter Docs, I've added a function that the button calls when pressed. The function simply displays a Label in the window. When I press the button a second time, I want it to remove the old Label and display a new Label. Instead grid_forget() is not removing the Label and it just repeats the Label on a new row.

Why is the Label widget not removed from the window? The code below illustrates the problem. I've read countless questions on here about removing widgets from display and using grid_forget().

The only thing I could think of was that the widget may be a local variable to displayText() and each time it is called by the button press, no display variable exists yet and the exception is raised. I tried making display a global variable, but it didn't work.

import Tkinter as tk

def displayText():
    try:
        display.grid_forget()
        display.destroy()
    except UnboundLocalError:
        #Display will not exist on first button press
        pass

    label = 'Hello World'
    display = tk.Label(text=label)
    #Also tried called display.grid_forget() here
    display.grid()
    display.bell()

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        self.grid(sticky=tk.N+tk.E+tk.W)
        self.createWidgets()
    def createWidgets(self):
        top=self.winfo_toplevel()
        top.geometry('300x100+50+50')
        top.rowconfigure(0, weight=1)
        top.columnconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.check = tk.Button(self, text='Say Hi', command=lambda : displayText())
        self.check.grid(row=0, column=0, sticky=tk.N+tk.E+tk.W)

app = Application()
app.master.title('Test App')
app.mainloop()

Upvotes: 0

Views: 390

Answers (1)

PRMoureu
PRMoureu

Reputation: 13347

You can assign the widget display to the main class in def __init__(), and move the function as a method. The goal is to keep a control on the widget during the time the app is running.

import Tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        self.grid(sticky=tk.N+tk.E+tk.W)
        self.createWidgets()
        self.display = None

    def createWidgets(self):
        top=self.winfo_toplevel()
        top.geometry('300x100+50+50')
        top.rowconfigure(0, weight=1)
        top.columnconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.check = tk.Button(self, text='Say Hi', command=self.displayText) 
        self.check.grid(row=0, column=0, sticky=tk.N+tk.E+tk.W)

    def displayText(self):
        if self.display:
            self.display.configure(text='hello new world')

        else:
            label = 'Hello World'
            self.display = tk.Label(text=label)
            #Also tried called display.grid_forget() here
            self.display.grid()
            self.display.bell()

app = Application()
app.master.title('Test App')
app.mainloop()

Upvotes: 1

Related Questions