在 Tkinter GUI 中动态添加和删除子框架

95 阅读2分钟

在使用 Tkinter 创建一个具有用户输入变量的 GUI 时,我们需要能够根据唯一的 ID 动态添加和删除子框架。这些子框架包含一些用户需要输入的变量,这些变量在将来需要通过唯一的 ID 来获取。

在这个问题中,我们遇到了三个具体的问题:

  1. 为什么显示每个框架标题的 Label 控件没有显示?

  2. 为什么有时需要按两次添加或删除按钮才能添加或删除框架?

  3. 在这种情况下,是否有更好的方法来跟踪框架实例(目前使用列表来跟踪)?

  1. 解决方案

    针对以上问题,解决方案如下:

    1. 显示标题:

      这个问题的原因是,在创建 Label 控件时,没有使用适当的 text 参数。正确的方法是使用 StringVar() 变量来设置文本,然后将其传递给 textvariable 参数。

    2. 避免需要按两次按钮:

      这个问题的原因是,在添加或删除框架时,没有正确地更新 self.numberself.sub_frame 的值。

    3. 选择更合适的数据结构来跟踪框架实例:

      为了更好地跟踪框架实例,可以使用一个具有适当方法的类来管理框架。这样可以更轻松地添加、删除和访问框架。

    以下是一个改进的代码示例:

import tkinter as tk

class FrameGroup(tk.Frame): def init(self, parent): tk.Frame.init(self, parent) self.all_instances = [] self.counter = 0

def Add(self):
    self.counter += 1
    name = "Frame %s" % self.counter
    subframe = Subframe(self, name=name)
    subframe.pack(side="left", fill="y")
    self.all_instances.append(subframe)

def Remove(self, instance):
    # don't allow the user to destroy the last item
    if len(self.all_instances) > 1:
        index = self.all_instances.index(instance)
        subframe = self.all_instances.pop(index)
        subframe.destroy()

def HowMany(self):
    return len(self.all_instances)

def ShowMe(self):
    for instance in self.all_instances:
        print(instance.get())

class Subframe(tk.Frame): def init(self, parent, name): tk.Frame.init(self, parent) self.parent = parent self.e1 = tk.Entry(self) self.e2 = tk.Entry(self) self.e3 = tk.Entry(self) label = tk.Label(self, text=name, anchor="center") add_button = tk.Button(self, text="Add", command=self.parent.Add) remove_button = tk.Button(self, text="Remove", command=lambda: self.parent.Remove(self))

    label.pack(side="top", fill="x")
    self.e1.pack(side="top", fill="x")
    self.e2.pack(side="top", fill="x")
    self.e3.pack(side="top", fill="x")
    add_button.pack(side="top")
    remove_button.pack(side="top")

def get(self):
    return (self.e1.get(), self.e2.get(), self.e3.get())

class GUI(tk.Tk): def init(self): tk.Tk.init(self) self.master_frame = tk.Frame(self) self.master_frame.grid() self.all_instances = FrameGroup(self.master_frame) self.all_instances.grid()

    # create the first frame
    self.all_instances.Add()

root = GUI() root.mainloop()


这个改进的代码示例解决了前面提到的问题。在 `Subframe` 类中,我们创建了 `get()` 方法来获取框架中用户输入的值。在 `FrameGroup` 类中,我们创建了 `Add()``Remove()` 方法来添加和删除框架。

通过这些改进,我们可以轻松地动态添加和删除框架,并使用 `FrameGroup` 类来管理和跟踪框架实例。