Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
528 views
in Technique[技术] by (71.8m points)

python - 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'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...