我有简单的代码,只需按一下按钮即可创建两个字段。还有两个其他按钮可以保存和加载创建的输入字段。我使用了bind
函数来绑定字段A和字段B。输入数字后,在字段A上按 Enter 按钮,将打印出其值乘以字段B中的5。点绑定功能可以很好地工作。
当我创建三个输入字段并保存进度而不输入任何输入并编译程序,然后加载文件时,bind函数似乎不起作用。它似乎仅对最后创建的字段起作用。我的代码如下。我尽力简化了代码。
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfile
from tkinter import messagebox
import pickle
class Test(Frame):
def Widgets(self):
self.button_add = Button(self, text = "Add", command = self.add)
self.button_add.grid(row=0, column =2)
self.button_save = Button(self, text = "save", command = self.save)
self.button_save.grid(row=0, column =3)
self.button_load = Button(self, text = "load", command = self.load)
self.button_load.grid(row=0, column =4)
def add(self):
def test(event):
self.field_B[n].delete(0, END)
self.field_B[n].insert(0, (float(self.field_A[n].get()))*5)
self.field_A.append({})
n = len(self.field_A)-1
self.field_A[n] = Entry(self)
self.field_A[n].grid(row=n, column =0)
self.field_A[n].bind("<Return>", test)
self.field_B.append({})
n = len(self.field_B)-1
self.field_B[n] = Entry(self)
self.field_B[n].grid(row=n, column =1)
def save(self):
for n in range(len(self.field_A)):
self.entry_A.append(self.field_A[n].get())
self.entry_B.append(self.field_B[n].get())
fname = asksaveasfile(mode = "w", defaultextension = ".est")
data = {"fields": len(self.field_A), "entries_A": (self.entry_A),"entries_B": (self.entry_B)}
with open(fname.name, "wb") as file:
pickle.dump(data, file)
def load(self):
def test(event):
print("Why is the value of n always equal to", n, "?")
self.field_B[n].delete(0, END)
self.field_B[n].insert(0, (float(self.field_A[n].get()))*5)
fname = askopenfilename(filetypes = (("Estimation Files (est)", "*.est"),))
location = fname.replace("/", "\\")
if location:
with open(location, "rb") as file:
data = pickle.load(file)
for n in range(data["fields"]):
self.field_A.append({})
self.field_A[n] = Entry(self)
self.field_A[n].grid(row=n, column =0)
self.field_A[n].insert(0, data["entries_A"][n])
self.field_A[n].bind("<Return>", test)
self.field_B.append({})
self.field_B[n] = Entry(self)
self.field_B[n].grid(row=n, column =1)
self.field_B[n].insert(0, data["entries_B"][n])
def __init__(self,master = None):
Frame.__init__(self, master)
self.field_A = []
self.field_B = []
self.entry_A = []
self.entry_B = []
self.grid()
self.Widgets()
root = Tk()
app = Test(master = None)
app.mainloop()
答案 0 :(得分:2)
您需要一个“关闭”。您可以使用functools.partial
函数在python中进行关闭。
from functools import partial
def test(n, event=None):
self.field_B[n].delete(0, END)
self.field_B[n].insert(0, (float(self.field_A[n].get()))*5)
#other code ...
self.field_A[n].bind("<Return>", partial(test, n))
答案 1 :(得分:1)
您的两个test()
函数都从封闭函数访问变量n
。对于add()
,没有循环; n
有一个值。每个条目的test()
都有自己的n
,因为它们受到对add()
的不同调用的约束。但是,在load()
中,您正在遍历n
值;每个test()
都引用同一个n
,在可能调用任何绑定时,它将具有最终值。另一个答案提供了一种合理的方式来为test()
的每个实例赋予其自己的个人n
,因此在这里我不再赘述。