在 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