Tkinter grid_forget is clearing the frame

    from tkinter import *
from PIL import ImageTk,Image
root=Tk()
root.title("Image Viewer")

def buttonforward(image_number):
    global myLabel
    myLabel.grid_forget()

    myLabel = Label(image=imagelist[image_number-1])
    myLabel.grid(row=0, column=0, columnspan=3)
    return
my_img1 = ImageTk.PhotoImage(Image.open('mountain1.jpg'))
my_img2 = ImageTk.PhotoImage(Image.open('mountain2.jpg'))
my_img3 = ImageTk.PhotoImage(Image.open('mountain3.jpg'))
my_img4 = ImageTk.PhotoImage(Image.open('mountain4.jpg'))
my_img5 = ImageTk.PhotoImage(Image.open('mountain5.jpg'))

myLabel = Label(image=my_img1, ).grid(row=0, column=0, columnspan=3)
imagelist = [my_img1, my_img2, my_img3, my_img4, my_img5]
button_back = Button(root, text='<<').grid(row=1,column=0)
button_exit = Button(root, text='Exit', padx=60, command=root.quit).grid(padx=60, row=1,column=1)
button_forward = Button(root, text='>>',command = lambda: buttonforward(2) ).grid(row=1,column=2)
root.mainloop()

myLabel.grid_forget() is not working and I am encountering the following error after I press the forward ‘>>’ button:
myLabel.grid_forget()
AttributeError: ‘NoneType’ object has no attribute ‘grid_forget’

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

seperate the grid method and it will work. Every function in Python needs to return something and if nothing is returned ‘None’ will set by default. So your variable will become myLabel = None.

Now that you know why that is bad behavior your should also do it for every other widget in your code.

.

Explaination

To show you what went wrong in your code look at this bit of code here:

import tkinter as tk

root = tk.Tk()
x1 = tk.Label(text='x1')
x1.pack()
print(x1)
root.mainloop()

the Output should be:

.!label

This tells me that x1 is assigned to the label.

Now take a look at this:

import tkinter as tk

root = tk.Tk()

x1 = tk.Label(text='x1')
returned_by_layoutmanager = x1.pack()
print(x1)
print(returned_by_layoutmanager)
root.mainloop()

Your Output will be:

.!label
None

If you may noticed, None was returned by the layoutmanger.
This is how python works, as soon as somthing is returned by a method/function the interpreter returns to the point he started reading the function/method. It’s like the function tells I’m done keep going.

So if you do this:

import tkinter as tk

root = tk.Tk()
x2 = tk.Label(text='x2').pack()
print(x2)
root.mainloop()

Your Output will be:

None

To understand why None is assigned to x2 and not to .!label by this line here:

x2 = tk.Label(text='x2').pack()

Try this:

import tkinter as tk

root = tk.Tk()

x1 = tk.Label(text='x1')
x1 = x1.pack()
print(x1)

root.mainloop()

Your Output will be:

None

Its just the same as you do it in your oneliner. First you assign x1 to the instance of Label class and then you assign x1 to None.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x