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