Tkinter:如何动态创建一个可以被销毁或移除的控件?

4 投票
2 回答
27778 浏览
提问于 2025-04-17 15:27

我想找一种方法,可以不停地创建小部件(可能是一个标签),但要能在之后把它们删除或拆除。

我可以顺利生成这些小部件,但它们没有名字。我不太明白,如果可以的话,怎么才能删除一个没有名字的小部件。

我最开始的想法是动态创建变量名,按照一个稳定的规则来命名,但这样可能会引发一些不必要的问题。我的想法如下。我希望能够在不知道运行时会处理多少个的情况下,删除某个按钮小部件。谢谢。

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)

编辑:我承认我的功能请求有些短视。我的最终目标是让一个标签小部件和一个按钮并排放置,这两个小部件将构成一个测试启动器中的一个“步骤”。点击按钮后,它会把自己和对应的标签从界面上移除。我可以创建这两个小部件,并在按钮的回调中删除其中一个,但要同时移除这两个小部件,我想我需要定义一个函数。我觉得我的问题在于如何正确地传递给def removeStep。下面有一个用例图示:....[如果这个问题能通过查阅手册解决,请随时告诉我,我就是找不到]

测试:制作花生酱和果酱三明治

步骤0:拿面包 [移除步骤]

步骤1:涂抹花生酱 [移除步骤]

步骤2:涂抹果酱 [移除步骤]

2 个回答

6

这里有几种选择。第一种选择是把你动态创建的按钮存放在一个列表里。这样你就可以随时添加或删除按钮,并且可以保持对所有按钮的引用。这种方法简单又干净。

第二种选择是在创建按钮后(并且你有这个按钮的引用)使用config方法来销毁这个控件——或者至少把它从显示中移除(widget.pack_forget 并不会真正销毁这个控件! 它可以在之后重新显示。如果你想真正销毁一个控件,你应该使用widget.destroy)...:

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()
10

你需要把动态创建的控件存储在一个列表里。可以这样做:

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)

接着只需创建一些叫做“步骤 0:买面包”的可移除任务实例,然后把它们在一列中排列好。其他的事情会自动处理。

撰写回答