tkinter:使用 window_create 彻底销毁在 tk.Text 中创建的自动包装小部件
tkinter: cleanly destroy auto-wrapping widgets created in tk.Text with window_create
基于 的回答,我成功创建了自己的小部件,其中标签使用 window_create
.
自动包装在 Text
元素中
我还可以使用 nametowidget
销毁这些标签。但是,删除的小部件的 window
元素仍然存在,并由 dump
.
返回
这是我的最小可重现示例:
import tkinter as tk
root = tk.Tk()
btn_frame1 = tk.Frame(root)
btn_frame1.pack(side='top', fill='x')
create_labels_btn = tk.Button(btn_frame1, text='Create Labels')
create_labels_btn.pack(side='left')
delete_labels_btn = tk.Button(btn_frame1, text='Delete Labels')
delete_labels_btn.pack(side='right')
label_text_field = tk.Text(root, height=7, width=40)
label_text_field.pack(side='top')
dump_text_field_btn = tk.Button(root, text='Dump text field')
dump_text_field_btn.pack(side='top')
dumping_text = tk.Text(root, height=7, width=40)
dumping_text.pack(side='top')
def create_labels():
for i in range(1, 7):
lbl = tk.Label(label_text_field, width=12, text=f'label {i}')
label_text_field.window_create("insert", window=lbl, padx=8, pady=8)
create_labels_btn['command'] = create_labels
def delete_labels():
for lbl in label_text_field.dump("1.0", "end"):
if lbl[0] =='window' and lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
delete_labels_btn['command'] = delete_labels
def dump_text_field():
dumping_text.delete("1.0", "end")
for obj in label_text_field.dump("1.0", "end"):
dumping_text.insert('end', str(obj) + '\n')
dump_text_field_btn['command'] = dump_text_field
root.mainloop()
创建和删除我的标签后。删除的元素在 dump
输出中仍然可见(虽然小部件已成功删除,但剩余的名称只是一个空字符串):
如何彻底删除关联的 window
,以免它们随着时间的推移而累加?
您需要使用 .dump()
编辑的 return 索引从 Text
小部件中删除项目。但是需要倒序去掉,否则去掉第一项后index会出错
def delete_labels():
for lbl in label_text_field.dump("1.0", "end")[::-1]: # get the items in reverse order
if lbl[0] =='window' and lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
label_text_field.delete(lbl[2]) # remove item from text box as well
实际上你只能传递 window=1
到 dump()
到 return window 项:
def delete_labels():
for lbl in label_text_field.dump("1.0", "end", window=1)[::-1]:
if lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
label_text_field.delete(lbl[2])
基于 window_create
.
Text
元素中
我还可以使用 nametowidget
销毁这些标签。但是,删除的小部件的 window
元素仍然存在,并由 dump
.
这是我的最小可重现示例:
import tkinter as tk
root = tk.Tk()
btn_frame1 = tk.Frame(root)
btn_frame1.pack(side='top', fill='x')
create_labels_btn = tk.Button(btn_frame1, text='Create Labels')
create_labels_btn.pack(side='left')
delete_labels_btn = tk.Button(btn_frame1, text='Delete Labels')
delete_labels_btn.pack(side='right')
label_text_field = tk.Text(root, height=7, width=40)
label_text_field.pack(side='top')
dump_text_field_btn = tk.Button(root, text='Dump text field')
dump_text_field_btn.pack(side='top')
dumping_text = tk.Text(root, height=7, width=40)
dumping_text.pack(side='top')
def create_labels():
for i in range(1, 7):
lbl = tk.Label(label_text_field, width=12, text=f'label {i}')
label_text_field.window_create("insert", window=lbl, padx=8, pady=8)
create_labels_btn['command'] = create_labels
def delete_labels():
for lbl in label_text_field.dump("1.0", "end"):
if lbl[0] =='window' and lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
delete_labels_btn['command'] = delete_labels
def dump_text_field():
dumping_text.delete("1.0", "end")
for obj in label_text_field.dump("1.0", "end"):
dumping_text.insert('end', str(obj) + '\n')
dump_text_field_btn['command'] = dump_text_field
root.mainloop()
创建和删除我的标签后。删除的元素在 dump
输出中仍然可见(虽然小部件已成功删除,但剩余的名称只是一个空字符串):
如何彻底删除关联的 window
,以免它们随着时间的推移而累加?
您需要使用 .dump()
编辑的 return 索引从 Text
小部件中删除项目。但是需要倒序去掉,否则去掉第一项后index会出错
def delete_labels():
for lbl in label_text_field.dump("1.0", "end")[::-1]: # get the items in reverse order
if lbl[0] =='window' and lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
label_text_field.delete(lbl[2]) # remove item from text box as well
实际上你只能传递 window=1
到 dump()
到 return window 项:
def delete_labels():
for lbl in label_text_field.dump("1.0", "end", window=1)[::-1]:
if lbl[1]:
label_text_field.nametowidget(lbl[1]).destroy()
label_text_field.delete(lbl[2])