【问题标题】:How should be deleted widgets that were create by a loop, in python tkinter?在 python tkinter 中,应该如何删除由循环创建的小部件?
【发布时间】:2021-03-31 11:58:06
【问题描述】:

我通过循环创建条目和标签。如果用户单击该按钮,则会在两两分隔的行中出现新条目和标签。现在我想通过单击其他按钮来删除它们,但标签不可删除 - 只有条目是。

我的另一个问题是我只想删除通过单击添加的最后一个小部件。说清楚:我想一键删除最后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()

【问题讨论】:

  • 这就是我试图删除它们的方式。但如果有人有更好的想法,那么我也愿意接受。
  • 尝试只使用pop(),然后将其存储为一个变量,然后将其删除,而不是使用for 循环?
  • nothingList2 是第一个代码块内的局部变量(假设它在函数内),因此无法在 deleteThem() 函数内访问。同样,deleteThem() 中的第一个 for 循环将清除 nothingList2(假设它可以在此处访问),因此第二个 for 循环将什么也不做。最好提供minimal reproducible example

标签: python tkinter tkinter-entry tkinter-label


【解决方案1】:

这里有一个解决方案(解释如下):

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()) 完成基本工作之后,您创建了一个字典来存储类。现在类在这里是一个重要因素,因为类的每个实例都可以独立运行,这实际上无法通过函数来​​实现,至少不那么容易。

然后,您可以为所需的任何小部件创建一个类,您可以为多个小部件创建多个类,或者以某种方式将它们全部合并为一个(不知道这将如何工作),但让我们为一种类型坚持一个类小部件。

在这个类中,你定义了所有你想要的小部件的基本东西,但你也添加了一个重要的参数“key”。这并不重要,但肯定是必要的,因为您不想将未使用的类留在内存中(不了解技术方面,但 imo 它可以使所有内容更加干净,特别是如果您出于某种原因必须阅读它[字典])

然后您定义删除函数,这就是类实例的独立性所在:对于每个类实例,您将能够调用这个只会影响该类实例的函数。所以现在在这个函数中,您将销毁该类创建的小部件(在本例中为self.button 中的按钮)或多个小部件。然后是清理部分:您全局定义字典,然后从中删除“键”。并且密钥还可以更容易地访问类实例,因为其他原因。

最后的说明。您可以像这样访问存储在字典函数中的类:dictionary[key].that_class_function

【讨论】:

  • 我想要一些时间来尝试将其转换为我的代码
  • @Nirevezs 当然,我并不着急。
  • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。
  • @CoolCloud 会做
  • @CoolCloud 现在好点了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
相关资源
最近更新 更多