我使用 while 循环制作了多个 tkinter 条目小部件,但我在为每个小部件定义单独的变量时遇到了问题

I have made multiple tkinter entry widgets usign a while loop, and I'm having issues defining separate variables for each one

我的部分程序提示用户在输入字段中输入样本编号,然后单击一个按钮,该按钮会在其下方生成该数量的条目小部件(以输入有关每个样本的信息)。输入小部件完全按照预期显示,对于输入的样本数量,一个位于另一个下方。 我现在无法弄清楚如何为每个新条目小部件分离变量。我曾希望每个人都允许我输入不同的值,然后通过 .get() 回调它们。事实并非如此,它们都会一起变成我输入的任何内容。以下是我认为是问题所在的代码部分:

normval_f= IntVar()
    x= samp.get()
    f=1
    while f<=x:
        f_entry = ttk.Entry(mainframe, width=7, textvariable=normval_f)
        f_entry.grid(column=1, row=f+12)
        f_label = ttk.Label(mainframe, text="Sample "+str(f)+ " value").grid(column=2, row=f+12, sticky=W)
        f=f+1        

几点建议;不要使用 while 循环,而是使用 for 循环。其次,我建议将每个变量存储在一个列表中,或者像我所做的那样,存储在一个列表中。目前,每次循环都会覆盖变量,因此每次都需要创建一个新变量并将其存储在某个地方。

下面是一个在字典中存储多个字段的例子。

from tkinter import *

class App(Frame):
    def __init__(self,master):
        Frame.__init__(self, master)
        fields = ['name','age','gender']
        self.field_variables = {}
        for idx,field in enumerate(fields):
            self.field_variables[field] = StringVar()
            f_entry = Entry(self,textvariable=self.field_variables[field])
            f_entry.grid(column=2,row=idx)
            f_label = Label(self,text=field)
            f_label.grid(column=1,row=idx)

        go_btn = Button(self,text="Go",command=self.get_all)
        go_btn.grid()

    def get_all(self):
        print(self.field_variables)

if __name__ == '__main__':
    root = Tk()
    app = App(root)
    app.grid()

列表和字典在处理大量或可能大量的小部件时非常有用。

下面是一些代码来完成您在问题中描述的内容。

我使用一个名为 self.my_entries 的列表来存储将根据用户输入的值创建的所有条目。我还添加了一些错误处理,以防用户尝试输入按下按钮时输入数字以外的内容或未输入任何内容。

第一个条目和按钮位于根部 window,对于将要创建的所有条目字段,我们在第一个按钮下方添加一个框架。如果我们以后想重置字段,这将使我们能够更轻松地管理输入字段。

from tkinter import *


class Example(Frame):


    def __init__(self):
        Frame.__init__(self)

        self.pack()   
        self.my_entries = []

        self.entry1 = Entry(self)
        self.entry1.grid(row = 0, column = 0)
        Button(self, text="Set Entry Fields", command=self.create_entry_fields).grid(row = 1, column = 0)

        self.frame2 = Frame(self)
        self.frame2.grid(row = 2, column = 0)

    def create_entry_fields(self):
        x = 0
        try:
            x = int(self.entry1.get())
            if x != 0:
                for i in range(x):
                    self.my_entries.append(Entry(self.frame2))
                    self.my_entries[i].grid(row=i, column=1)
                    f_label = Label(self.frame2, text="Label {}: ".format(i+1))
                    f_label.grid(row=i, column=0)
            Button(self.frame2, text="Print to console", command=self.print_all_entries).grid(row=x, column=0, sticky = "nsew")
            Button(self.frame2, text="Reset", command=self.clear_frame2).grid(row=x, column=1, sticky = "nsew")
        except:
            print("Invalid entry. Only numbers are allowed.")

    def print_all_entries(self):
        for i in self.my_entries:
            print(i.get())

    def clear_frame2(self):
        self.my_entries = []
        self.frame2.destroy()
        self.frame2 = Frame(self)
        self.frame2.grid(row = 2, column = 0)


if __name__ == '__main__':
    root = Tk()
    test_app = Example()
    root.mainloop()

如果您对上述代码有任何疑问,请告诉我。