Python 如何从窗口中删除Tkinter小部件?

Python 如何从窗口中删除Tkinter小部件?,python,tkinter,Python,Tkinter,我有一个要动态更改的tkinter小部件列表 如何从窗口中删除小部件?您可以调用以删除小部件(如果您使用将其添加到窗口中) 例如: from tkinter import * root = Tk() b = Button(root, text="Delete me", command=lambda: b.pack_forget()) b.pack() root.mainloop() 如果您使用pack\u-forget,您可以稍后再次显示小部件,再次调用pack。如果您想永久删除它,请在

我有一个要动态更改的
tkinter
小部件列表

如何从窗口中删除小部件?

您可以调用以删除小部件(如果您使用将其添加到窗口中)

例如:

from tkinter import *

root = Tk()

b = Button(root, text="Delete me", command=lambda: b.pack_forget())
b.pack()

root.mainloop()
如果您使用
pack\u-forget
,您可以稍后再次显示小部件,再次调用
pack
。如果您想永久删除它,请在小部件上调用
destroy
(然后您将无法重新添加它)


如果使用该方法,可以使用或
grid\u remove
隐藏小部件。

我发现,当小部件是一个函数的一部分,而
grid\u remove
是另一个函数的一部分时,它不会删除标签。在这个例子中

def somefunction(self):
    Label(self, text=" ").grid(row = 0, column = 0)
    self.text_ent = Entry(self)
    self.text_ent.grid(row = 1, column = 0)
def someotherfunction(self):
    somefunction.text_ent.grid_remove()
…没有删除标签的有效方法

我能找到的唯一解决方案是给标签起一个名字,并使其全球化:

def somefunction(self):
    global label
    label = Label(self, text=" ")
    label.grid(row = 0, column = 0)
    self.text_ent = Entry(self)
    self.text_ent.grid(row = 1, column = 0)
def someotherfunction(self):
    global label
    somefunction.text_ent.grid_remove()
    label.grid_remove()

当我遇到这个问题时,涉及到一个类,一个函数在类中,一个不在类中,因此我不确定上面是否真的需要
全局标签行。

一种方法是从需要清除的帧中获取从属列表,并根据需要销毁或“隐藏”它们。要获得清晰的画面,您可以这样做:

from tkinter import *

root = Tk()

def clear():
    list = root.grid_slaves()
    for l in list:
        l.destroy()

Label(root,text='Hello World!').grid(row=0)
Button(root,text='Clear',command=clear).grid(row=1)

root.mainloop()
lbl = tk.Label(....)

btn = tk.Button(....., command=lambda: lbl.destroy())

您应该调用
grid\u slaves()
pack\u slaves()
slaves()
,这取决于您将小部件添加到框架中所使用的方法。

今天,我学习了一些使用python3中的tkinter gui库进行的简单而好的点击事件处理,我想在这个线程中与大家分享

from tkinter import *

cnt = 0


def MsgClick(event):
    children = root.winfo_children()
    for child in children:
        # print("type of widget is : " + str(type(child)))
        if str(type(child)) == "<class 'tkinter.Message'>":
            # print("Here Message widget will destroy")
            child.destroy()
            return

def MsgMotion(event):
  print("Mouse position: (%s %s)" % (event.x, event.y))
  return


def ButtonClick(event):
    global cnt, msg
    cnt += 1
    msg = Message(root, text="you just clicked the button..." + str(cnt) + "...time...")
    msg.config(bg='lightgreen', font=('times', 24, 'italic'))
    msg.bind("<Button-1>", MsgClick)
    msg.bind("<Motion>", MsgMotion)
    msg.pack()
    #print(type(msg)) tkinter.Message


def ButtonDoubleClick(event):
    import sys; sys.exit()


root = Tk()

root.title("My First GUI App in Python")
root.minsize(width=300, height=300)
root.maxsize(width=400, height=350)
button = Button(
    root, text="Click Me!", width=40, height=3
)
button.pack()
button.bind("<Button-1>", ButtonClick)
button.bind("<Double-1>", ButtonDoubleClick)

root.mainloop()
从tkinter导入*
cnt=0
def MsgClick(事件):
children=root.winfo_children()
对于儿童中的儿童:
#打印(“小部件类型为:”+str(类型(子)))
如果str(类型(子))==“”:
#打印(“此处消息小部件将销毁”)
child.destroy()
返回
def MsgMotion(事件):
打印(“鼠标位置:(%s%s)”%(事件x,事件y))
返回
def按钮单击(事件):
全球碳纳米管
cnt+=1
msg=Message(root,text=“您刚刚单击了按钮…”+str(cnt)+“…时间…”)
msg.config(bg='lightgreen',font=('times',24',italic'))
msg.bind(“,MsgClick)
msg.bind(“,MsgMotion)
msg.pack()
#打印(键入(msg))tkinter.Message
def按钮双击(事件):
导入系统;sys.exit()
root=Tk()
title(“我在Python中的第一个GUI应用程序”)
root.minsize(宽度=300,高度=300)
root.maxsize(宽=400,高=350)
按钮(
root,text=“单击我!”,宽度=40,高度=3
)
button.pack()
button.bind(“,ButtonClick)
button.bind(“,ButtonDoubleClick)
root.mainloop()

希望它能帮助某人…

您可以在小部件上使用遗忘方法

from tkinter import * root = Tk() b = Button(root, text="Delete me", command=b.forget) b.pack() b['command'] = b.forget root.mainloop() 从tkinter进口* root=Tk() b=按钮(root,text=“删除我”,command=b.forget) b、 包() b['command']=b root.mainloop()
只需使用
destroy()
方法删除指定的小部件,如下所示:

from tkinter import *

root = Tk()

def clear():
    list = root.grid_slaves()
    for l in list:
        l.destroy()

Label(root,text='Hello World!').grid(row=0)
Button(root,text='Clear',command=clear).grid(row=1)

root.mainloop()
lbl = tk.Label(....)

btn = tk.Button(....., command=lambda: lbl.destroy())

使用它,您可以完全销毁特定的小部件。

您说您有一个要动态更改的小部件列表。您想重用和重新配置现有的小部件,还是创建所有新的小部件并删除旧的小部件?这会影响答案

如果您想重用现有的小部件,只需重新配置它们。或者,如果您只是想暂时隐藏其中一些,请使用相应的“忘记”方法来隐藏它们。如果您使用
pack()
调用映射它们,您将使用
pack\u-forget()
(或仅使用
forget()
)调用隐藏它们。因此,
grid\u-forget()
用于隐藏网格化的小部件,而
place\u-forget()
用于放置的小部件

如果不打算重用小部件,可以直接调用
destroy()
来销毁它们,如
widget.destroy()
,以释放资源。


clear_btm=Button(master,text="Clear") #this button will delete the widgets 
clear_btm["command"] = lambda one = button1, two = text1, three = entry1: clear(one,two,three) #pass the widgets
clear_btm.pack()

def clear(*widgets):
    for widget in widgets:
        widget.destroy() #finally we are deleting the widgets.

@TheBeardBerry:请注意,
pack\u-forget
不会删除小部件,它只会将它们从视图中删除。它们仍然会存在,如果你继续重新创建小部件而不销毁它们,可能会导致内存泄漏。如果我
pack\u-forget
一个框架,然后将其删除,它会同时删除子小部件吗,还是应该单独删除它们?你能为place而不是pack做类似
place\u-forget
的事情吗?@stegosaurs:Yes,还有一种方法。无法删除您创建的第一个标签这一事实与您在一个函数中创建标签并在另一个函数中删除标签这一事实无关,只是您无法保留引用。这不是tkinter的事情,而是编程的事情——要对一个对象进行操作,必须有一个对该对象的引用。在第二个示例中,不需要使用全局变量。相反,将其分配给
self
,就像您分配条目小部件一样。这应该是问题的答案吗?如果没有,请将其删除。如果是这样,你需要澄清这与删除小部件的关系。是的,这不是一个你可以走进的花园。这里的人们希望找到问题的答案,而不仅仅是随机的代码片段。不过,你的代码并不能回答问题。你不能只是在一个线程中发布随机的东西,因为这不是线程的用途。我在一个窗口中有5个按钮。然后我需要添加3个新按钮并删除旧按钮。但是窗户上有两个旧钮扣。使用此解决方案,将删除所有5个按钮,只添加3个新按钮。我对我的应用程序使用MVP模式。在for循环中,你需要处理谁将被删除,谁将被删除。请在代码中添加一些上下文或注释,以便作者和其他人能够轻松理解。这将引发错误,因为未定义
b