在 python tkinter 中,应该如何删除循环创建的小部件?
How should be deleted widgets that were create by a loop, in python tkinter?
我通过循环创建条目和标签。如果用户单击该按钮,将在两两分隔的行中出现新的条目和标签。现在我想通过点击其他按钮来删除它们,但是标签是不可删除的——只有条目是。
我的另一个问题是我只想删除最后一次单击添加的小部件。说清楚:我想一键删除最后18-18个标签和词条。目前,到目前为止添加的所有条目都将被删除。标签根本没有。
相关代码如下:
self._1thLabel_list = ['Label1', 'Label2', 'Label3', 'Label4', 'Label5',
'Label6', 'Label7', 'Label8', 'Label9']
self._2thLabel_list = ['Label10', 'Label11', 'Label12', 'Label13', 'Label14',
'Label15', 'Label16', 'Label17', 'Label18']
nothingList2 = []
self.col = 4
for j in range(len(self._1thLabel_list)):
self.myLab = Label(root, text=self._1thLabel_list[j]).grid(row=0, column=j+1)
for k in range(1):
self.myEntry_loop = Entry(root)
self.myEntry_loop.grid(row=k + 1, column=j+1, pady=10, padx=10)
self.myEntry_loop_2 = Entry(root)
self.myEntry_loop_2.grid(row=k + 3, column=j + 1, pady=10, padx=10)
nothingList2.append(self.myEntry_loop)
nothingList2.append(self.myEntry_loop_2)
for l in range(len(self._2thLabel_list)):
self.myLab_2 = Label(root, text=self.mylist_2[l]).grid(row=2, column=l + 1)
self.myButton_newWidgets = Button(root, text="Add", command=self.Add)
self.myButton_newWidgets.grid(row=self.col, column=4)
self.myButton_deleteWidgets = Button(root, text="Delete", command=self.deleteThem)
self.myButton_deleteWidgets.grid(row=self.col, column=5)
以下是尝试删除它们的方法:
def deleteThem(self):
for v in range(18):
nothingList2.pop(0)
for dele in nothingList2:
dele.destroy() # Here, it is deleting entries but delete all of them. I want just delete the last 18 of them.
for w in range(9):
self._1thLabel_list.pop(0)
for delet in self._1thLabel_list:
delet.destroy() # I got "AttributeError: 'str' object has no attribute 'destroy'" error in this line
for x in range(9):
self._2thLabel_list.pop(0)
for delet2 in self._2thLabel_list:
delet2.destroy()
这是一个解决方案(解释如下):
from tkinter import Tk, Button
root = Tk()
removable_widget_dict = {}
class RemovableWidget(Button):
def __init__(self, parent, title, key):
Button.__init__(self, parent)
self.key = key
self.config(text=title)
self.pack()
def delete(self):
self.destroy()
removable_widget_dict.pop(self.key)
for i in range(10):
key = f'item{i}'
removable_widget_dict[key] = RemovableWidget(root, f'Button {i}', key)
for key in removable_widget_dict.keys():
if key == 'item5':
removable_widget_dict[key].delete()
break
root.mainloop()
解释:
首先,我想提一下,这是我在做个人项目时想到的(至少与此类似),所以所有这些都来自经验,从某种意义上说,这可能不是最好的解决方案但它确实有效。
在使用 tkinter (root = Tk()
, root.mainloop()
) 完成基本操作后,您创建了一个字典来存储 classes。现在 classes 在这里是一个重要因素,因为 class 的每个实例都可以独立行动,这不能用函数真正实现,至少不那么容易。
那么您可以为您需要的任何小部件创建一个 class,您可以为多个小部件创建多个 class 或以某种方式将它们全部合并为一个(不知道如何工作) ) 但让我们坚持一个 class 用于一种类型的小部件。
在这个 class 中,您可以定义小部件所需的所有基本内容,还可以添加一个重要的参数“key”。这不是很重要,但肯定是必要的,因为你不想在内存中留下未使用的 classes(不知道技术方面,但我认为它让一切都更干净,特别是如果你必须阅读它[字典] ]出于某种原因)
然后定义删除函数,这就是 class 实例的独立性所在:对于每个 class 实例,您将能够调用此函数,它只会影响 class 实例。因此,现在在此函数中,您将销毁 class 创建的小部件(在本例中为 self.button
中的按钮)或多个小部件。然后是清理部分:您全局定义字典,然后从中删除“键”。并且由于其他原因,该密钥还可以更轻松地访问 class 实例。
最后的说明。您可以像这样访问存储在字典函数中的 classes:dictionary[key].that_class_function
我通过循环创建条目和标签。如果用户单击该按钮,将在两两分隔的行中出现新的条目和标签。现在我想通过点击其他按钮来删除它们,但是标签是不可删除的——只有条目是。
我的另一个问题是我只想删除最后一次单击添加的小部件。说清楚:我想一键删除最后18-18个标签和词条。目前,到目前为止添加的所有条目都将被删除。标签根本没有。 相关代码如下:
self._1thLabel_list = ['Label1', 'Label2', 'Label3', 'Label4', 'Label5',
'Label6', 'Label7', 'Label8', 'Label9']
self._2thLabel_list = ['Label10', 'Label11', 'Label12', 'Label13', 'Label14',
'Label15', 'Label16', 'Label17', 'Label18']
nothingList2 = []
self.col = 4
for j in range(len(self._1thLabel_list)):
self.myLab = Label(root, text=self._1thLabel_list[j]).grid(row=0, column=j+1)
for k in range(1):
self.myEntry_loop = Entry(root)
self.myEntry_loop.grid(row=k + 1, column=j+1, pady=10, padx=10)
self.myEntry_loop_2 = Entry(root)
self.myEntry_loop_2.grid(row=k + 3, column=j + 1, pady=10, padx=10)
nothingList2.append(self.myEntry_loop)
nothingList2.append(self.myEntry_loop_2)
for l in range(len(self._2thLabel_list)):
self.myLab_2 = Label(root, text=self.mylist_2[l]).grid(row=2, column=l + 1)
self.myButton_newWidgets = Button(root, text="Add", command=self.Add)
self.myButton_newWidgets.grid(row=self.col, column=4)
self.myButton_deleteWidgets = Button(root, text="Delete", command=self.deleteThem)
self.myButton_deleteWidgets.grid(row=self.col, column=5)
以下是尝试删除它们的方法:
def deleteThem(self):
for v in range(18):
nothingList2.pop(0)
for dele in nothingList2:
dele.destroy() # Here, it is deleting entries but delete all of them. I want just delete the last 18 of them.
for w in range(9):
self._1thLabel_list.pop(0)
for delet in self._1thLabel_list:
delet.destroy() # I got "AttributeError: 'str' object has no attribute 'destroy'" error in this line
for x in range(9):
self._2thLabel_list.pop(0)
for delet2 in self._2thLabel_list:
delet2.destroy()
这是一个解决方案(解释如下):
from tkinter import Tk, Button
root = Tk()
removable_widget_dict = {}
class RemovableWidget(Button):
def __init__(self, parent, title, key):
Button.__init__(self, parent)
self.key = key
self.config(text=title)
self.pack()
def delete(self):
self.destroy()
removable_widget_dict.pop(self.key)
for i in range(10):
key = f'item{i}'
removable_widget_dict[key] = RemovableWidget(root, f'Button {i}', key)
for key in removable_widget_dict.keys():
if key == 'item5':
removable_widget_dict[key].delete()
break
root.mainloop()
解释:
首先,我想提一下,这是我在做个人项目时想到的(至少与此类似),所以所有这些都来自经验,从某种意义上说,这可能不是最好的解决方案但它确实有效。
在使用 tkinter (root = Tk()
, root.mainloop()
) 完成基本操作后,您创建了一个字典来存储 classes。现在 classes 在这里是一个重要因素,因为 class 的每个实例都可以独立行动,这不能用函数真正实现,至少不那么容易。
那么您可以为您需要的任何小部件创建一个 class,您可以为多个小部件创建多个 class 或以某种方式将它们全部合并为一个(不知道如何工作) ) 但让我们坚持一个 class 用于一种类型的小部件。
在这个 class 中,您可以定义小部件所需的所有基本内容,还可以添加一个重要的参数“key”。这不是很重要,但肯定是必要的,因为你不想在内存中留下未使用的 classes(不知道技术方面,但我认为它让一切都更干净,特别是如果你必须阅读它[字典] ]出于某种原因)
然后定义删除函数,这就是 class 实例的独立性所在:对于每个 class 实例,您将能够调用此函数,它只会影响 class 实例。因此,现在在此函数中,您将销毁 class 创建的小部件(在本例中为 self.button
中的按钮)或多个小部件。然后是清理部分:您全局定义字典,然后从中删除“键”。并且由于其他原因,该密钥还可以更轻松地访问 class 实例。
最后的说明。您可以像这样访问存储在字典函数中的 classes:dictionary[key].that_class_function