Python 如何清除tkinter画布的一部分,并在按下submit时显示内容?

Python 如何清除tkinter画布的一部分,并在按下submit时显示内容?,python,tkinter,tkinter-canvas,Python,Tkinter,Tkinter Canvas,我正在创建一个简单的madlib风格的游戏,我遇到了一点问题。我无法清除画布并显示结果 下面的代码将图像放置为画布的背景。然后,它将所有要插入的单词的标签和输入字段放在两列中。页面底部有一个提交按钮。除了背景图像,我不知道如何把所有的东西都弄清楚,这样它就可以在用户插入文字的情况下显示故事。如果我把它放在callback()中,它只清除背景并保留所有其他内容。我想要相反的结果 from tkinter import * from PIL import Image, ImageTk canvas

我正在创建一个简单的madlib风格的游戏,我遇到了一点问题。我无法清除画布并显示结果

下面的代码将图像放置为画布的背景。然后,它将所有要插入的单词的标签和输入字段放在两列中。页面底部有一个提交按钮。除了背景图像,我不知道如何把所有的东西都弄清楚,这样它就可以在用户插入文字的情况下显示故事。如果我把它放在callback()中,它只清除背景并保留所有其他内容。我想要相反的结果

from tkinter import *
from PIL import Image, ImageTk

canvas_width = 360
canvas_height = 525
file = r"C:\Users\kraak\Desktop\PyCharm Community Edition 2017.1.2\borderedpaper.GIF"
master = Tk()
canvas = Canvas(master, width=canvas_width, height=canvas_height)

old_img = PhotoImage(file=file)
new_img = old_img.subsample(3, 3)
canvas.create_image(-11, -10, anchor=NW, image=new_img)
canvas.create_window(0, 0, height=1, width=1, anchor=NW)
canvas.create_text(0, 0, text="Test")

e1 = Entry(canvas)
canvas.create_window(250, 60, window=e1, height=15, width=100)
label = Label(text="Enter an adjective.")
label.place(x=40, y=50)
e1.focus_set()

e2 = Entry(canvas)
canvas.create_window(250, 85, window=e2, height=15, width=100)
label = Label(text="Enter a nationality.")
label.place(x=40, y=75)
e2.focus_set()


def callback():
    print("Pizza was invented by a " + (e1.get()) + " " + (e2.get()))

def answer():
    button = Button(text="Submit.", command=callback)
    button.place(x=150, y=460)

answer()
canvas.pack()


mainloop()

每个小部件都有一个
destroy
方法,可用于删除小部件。在回调中,您可以简单地为每个小部件调用此方法:

def callback():
    e1.destroy()
    e2.destroy()
    ...

在特定情况下,如果要删除所有标签,则必须为其指定唯一的名称。或者,为了使这更容易,您可以存储所有小部件并在列表中迭代。

正如Bryan Oakley所建议的,您可以将要删除的小部件的id存储在列表中,以便于
回调()函数中销毁它们。这里显示了对代码的修改,可以做到这一点,请注意添加了注释的行

from tkinter import *
from PIL import Image, ImageTk

canvas_width = 360
canvas_height = 525
file = r"C:\Users\kraak\Desktop\PyCharm Community Edition 2017.1.2\borderedpaper.GIF"
master = Tk()
canvas = Canvas(master, width=canvas_width, height=canvas_height)
canvas_entry_widgets = []  # ADDED

old_img = PhotoImage(file=file)
new_img = old_img.subsample(3, 3)
canvas.create_image(-11, -10, anchor=NW, image=new_img)
canvas.create_window(0, 0, height=1, width=1, anchor=NW)
canvas.create_text(0, 0, text="Test")

e1 = Entry(canvas)
canvas.create_window(250, 60, window=e1, height=15, width=100)
label = Label(text="Enter an adjective.")
label.place(x=40, y=50)
e1.focus_set()
canvas_entry_widgets.append(e1)  # ADDED

e2 = Entry(canvas)
canvas.create_window(250, 85, window=e2, height=15, width=100)
label = Label(text="Enter a nationality.")
label.place(x=40, y=75)
e2.focus_set()
canvas_entry_widgets.append(e2)  # ADDED

def callback():
    print("Pizza was invented by a " + (e1.get()) + " " + (e2.get()))
    # destroy the canvas entry widgets and clear the list  # ADDED
    while canvas_entry_widgets:                            # ADDED
        widget = canvas_entry_widgets.pop()                # ADDED
        widget.destroy()                                   # ADDED

def answer():
    button = Button(text="Submit.", command=callback)
    button.place(x=150, y=460)

answer()
canvas.pack()

mainloop()

请创建一个。如果您的问题是清除画布,那么您的示例中不需要十几个条目小部件和标签。您所说的“清除”是什么意思?您想删除所有小部件,还是简单地将条目小部件和/或标签重置为空?我已根据要求缩短了示例。我想删除所有的小部件,除了背景图像。删除所有内容后,我希望用户插入的答案与故事一起打印。我曾考虑过使用列表做同样的事情,但您无法销毁列表。@MichaelPhillips:但您可以遍历列表中的元素,并调用每个元素
destroy()
方法。