Python Tkinter:我如何动态创建一个小部件,然后销毁或删除它?

Python Tkinter:我如何动态创建一个小部件,然后销毁或删除它?,python,user-interface,tkinter,Python,User Interface,Tkinter,我正在寻找一种方法来创建令人厌恶的小部件(最有可能是一个标签),并警告它们以后可以删除或解包 我可以很好地生成小部件,但是没有为它们指定名称。我不明白如果可能的话,我如何删除某个匿名小部件 我的第一反应是用一个稳定的约定动态创建变量名,但这可能会不必要地打开一罐蠕虫。这一想法表达如下。我希望能够删除某个按钮小部件,同时不知道在运行时我将处理多少。多谢各位 from Tkinter import * import time import ttk def onDoubleClick(event)

我正在寻找一种方法来创建令人厌恶的小部件(最有可能是一个标签),并警告它们以后可以删除或解包

我可以很好地生成小部件,但是没有为它们指定名称。我不明白如果可能的话,我如何删除某个匿名小部件

我的第一反应是用一个稳定的约定动态创建变量名,但这可能会不必要地打开一罐蠕虫。这一想法表达如下。我希望能够删除某个按钮小部件,同时不知道在运行时我将处理多少。多谢各位

from Tkinter import *
import time
import ttk


def onDoubleClick(event):
    item = t.selection()
 #print "you clicked on", t.item(item,"text")

    if (t.item(item,"text")=="Start IO"):
        Button2 = Button(frame2,text="Button2",command=but).pack()


def but():
    pack_forget()

root=Tk()
root.geometry("800x300")
frame1 = Frame(root)
frame2 = Frame(root)

t=ttk.Treeview(frame1)
t.heading("#0",text="Test steps")
t.insert("",0,"IO",text="IO")
t.insert("IO","end",text="Start")
t.bind("<Double-1>", onDoubleClick)
t.pack()
frame1.pack(side=LEFT)
frame2.pack(side=LEFT)
从Tkinter导入*
导入时间
导入ttk
def onDoubleClick(事件):
项目=t.选择()
#打印“您点击的”,t.item(item,“text”)
如果(t.item(item,“text”)=“Start IO”):
Button2=按钮(frame2,text=“Button2”,command=but).pack()
def but():
打包
root=Tk()
根几何(“800x300”)
frame1=帧(根)
frame2=帧(根)
t=ttk.Treeview(frame1)
t、 标题(“0”,text=“测试步骤”)
t、 插入(“,0,“IO”,text=“IO”)
t、 插入(“IO”,“结束”,text=“开始”)
t、 绑定(“,onDoubleClick)
t、 包()
框架1.包装(侧面=左侧)
框架2.包装(侧面=左侧)
编辑:我的功能要求显然是短视的。我的最终目标是拥有一个标签小部件和一个并排的按钮,两者都包含测试启动程序中的“步骤”。单击该按钮将从GUI中删除其自身及其相应的标签。我可以创建这两个小部件,并在按钮的回调中删除其中一个,但要打包并忘记这两个小部件,我相信我需要定义一个函数。我相信我的问题在于将正确的引用传递给def removeStep用例如下图所示:…[如果这可以解决,我的RTFM请随时通知我,我就是找不到它]

测试:制作一个PB&J

步骤0:获取面包[移除步骤]

步骤1:涂抹PB[移除步骤]


步骤2:涂抹果冻[删除步骤]

您需要将动态创建的小部件存储在列表中。有点像

dynamic_buttons = []

def onDoubleClick(event):
    ...
    button = Button(...)
    dynamic_buttons.append(button)
    button.pack()
然后,您可以访问按钮以进行删除,例如

dynamic_buttons[0].destroy()
编辑:如果有更多关于您的用例的信息,我可能会这样做

class RemovableTask(Frame):
    def __init__(self, master, name, **options):
        Frame.__init__(self, master, **options)
        lbl = Label(self, text=name)
        btn = Button(self, text='Remove step', command=self.destroy)
        lbl.grid(row=0, column=0)
        btn.grid(row=0, column=1)

然后只需创建名为“Step0:Get-Bread”的RemovableTask实例,并将其网格化或打包到列中。其他一切都将自动处理。

您在这里有几个选项。第一个选项是将动态创建的按钮存储在列表中。然后,您可以随时添加/删除按钮,并保留对所有按钮的引用。干净简单

第二个选项是在创建按钮(并对其进行引用)后使用
config
方法销毁小部件,或者至少将其从显示中删除(
widget.pack\u forget
实际上不会销毁该小部件!稍后可以重新打包。要实际销毁小部件,您需要调用
widget.destroy
):


如果单击按钮时只需将其删除,这会更干净。但是,如果您想让按钮做的不仅仅是删除自身,那么配置版本就会变得混乱。@AbeKarplus--这实际上取决于OP试图用按钮实现什么。最终,
列表
解决方案会在某种程度上保留t哪个按钮的框架位于哪个索引处。但是,这个(第二个)解决方案存在问题,因为您没有对所讨论的按钮进行良好的引用——但是,在销毁自身之前,很容易让按钮执行其他操作。
b.config(command=lambda:do_something_with_b(b))
--但最终你是对的,除非该函数找到销毁
b
的方法,否则要用其他方法消除它是很困难的。这对我来说似乎是内存泄漏--你从视图中删除了小部件,但你从来没有销毁过它。@BryanOakley--因此我的评论是不实际销毁小部件…无论如何,我已经详细阐述了有关小部件的一些信息。销毁,并在我的原始评论中添加了重点。感谢您的评论。
import Tkinter as tk

root = tk.Tk()

def add_new():
    b = tk.Button(root,text="Click to destroy")
    b.pack()
    b.config(command=b.pack_forget) 

b = tk.Button(root,text="Add_new",command=add_new)
b.pack()
root.mainloop()