Как удалить виджеты Tkinter из окна?
У меня есть список виджетов Tkinter, которые я хочу динамически менять.
Как я могу полностью удалить виджеты из моего окна?
9 ответов
Ты можешь позвонить pack_forget
удалить виджет (если вы используете pack
добавить его в окно).
Пример:
from tkinter import *
root = Tk()
b = Button(root, text="Delete me", command=lambda: b.pack_forget())
b.pack()
root.mainloop()
Если вы используете pack_forget
позже вы сможете снова показать виджет pack
снова. Если вы хотите удалить его навсегда, позвоните destroy
на виджете (тогда вы не сможете его повторно добавить).
Если вы используете grid
метод, вы можете использовать grid_forget
или же 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()
Вам следует позвонить grid_slaves()
, pack_slaves()
или же slaves()
в зависимости от метода, который вы использовали, чтобы добавить виджет в кадр.
Вы просто используете destroy()
метод удаления указанных виджетов следующим образом:
lbl = tk.Label(....)
btn = tk.Button(....., command=lambda: lbl.destroy())
Используя это, вы можете полностью уничтожить определенные виджеты.
Вы говорите, что у вас есть список виджетов, которые нужно динамически изменять. Вы хотите повторно использовать и перенастроить существующие виджеты или создать все новые виджеты и удалить старые? Это влияет на ответ.
Если вы хотите повторно использовать существующие виджеты, просто перенастройте их. Или, если вы просто хотите временно скрыть некоторые из них, используйте соответствующий метод "забыть", чтобы скрыть их. Если вы сопоставили их сpack()
звонки, вы бы спрятались с pack_forget()
(или просто forget()
) звонки. Соответственно,grid_forget()
чтобы скрыть виджеты с сеткой, и place_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.
Вы можете использовать следующую функцию, если хотите удалить виджеты на основе индексов строк и столбцов. Обратите внимание, что вы можете выбрать метод_forget()
метод на основе используемого вами менеджера макетов.
def remove_widgets_based_on_location(master, rows, cols):
# list widgets to be removed
widgets = []
for row in rows:
for col in cols:
l = master.grid_slaves(row, col)
for i in l:
widgets.append(i)
# remove widgets
for widget in widgets:
widget.grid_forget()
# widget.pack_forget()
# widget.place_forget()
Например, если вы хотите удалить виджеты изroot
рамка на первых трех строках и первых двух столбцах:
remove_widgets_based_on_location(master = root,
rows = [0, 1, 2],
cols = [0, 1])
Я обнаружил, что когда виджет является частью функции и grid_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()
Когда я столкнулся с этой проблемой, был задействован класс, одна функция была в классе, а другая - нет, поэтому я не уверен, что global label
линии действительно необходимы в вышеупомянутом.
Вы можете использовать метод забудьте на виджете
из ткинтера импорт * root = Tk () b = кнопка (root, text="Удалить меня", command = b.forget) b.pack () root.mainloop ()
Сегодня я изучаю простую и удобную обработку событий кликов с помощью библиотеки tkinter gui в python3, которой я хотел бы поделиться в этой теме.
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()
Надеюсь, это поможет кому-то...