酸洗后无法绑定功能-Tkinter

时间:2018-11-10 06:01:31

标签: python-3.x tkinter pickle

我有简单的代码,只需按一下按钮即可创建两个字段。还有两个其他按钮可以保存和加载创建的输入字段。我使用了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()

2 个答案:

答案 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,因此在这里我不再赘述。