为什么tk键绑定在这里不起作用?

时间:2014-11-13 18:01:13

标签: python tkinter tk key-bindings

以下是代码:

#!/usr/bin/env python3
################################################################
### Solve the unknown
################################################################
class App:
    def __init__(self, root):
        self.fields = ["A", "B", "AB"]
        self.root = root
        self.entries = []
        self.numerics = []
        self.makeRows()
        Button(self.root, text="Run", command=self.run).grid(row=3, column=0)
        Button(self.root, text="Reset", command=self.reset).grid(row=3, column=1)
        root.bind("<Return>", self.run)
        root.bind("<space>", self.reset)

    def makeRows(self):
        for i in range(len(self.fields)):
            label = Label(self.root, text=self.fields[i], justify=LEFT)
            entry = Entry(self.root)
            label.grid(row=i, sticky=W)
            entry.grid(row=i, column=1)
            self.entries.append(entry)

    def getValues(self):
        try:
            values = [e.get() for e in self.entries]
            self.numerics = [float(v) if v!="" else v for v in values]
            print(self.numerics)
        except ValueError:
            messagebox.showerror(title="Error", message="Input only numerical values!")
            self.numerics = []

    def checkEmpty(self, elem):
        if elem == "":
            return 1
        else:
            return 0

    def checkEmptyInEntries(self):
        if len(self.numerics) != 0:
            entry_emptiness = [self.checkEmpty(v) for v in self.numerics]
            if sum(entry_emptiness) != 1:
                messagebox.showerror(title="Error", message="Leave one and only one entry empty!")
                return None
            return entry_emptiness
        else:
            return None

    def run(self):
        self.getValues()
        emptiness = self.checkEmptyInEntries()
        if emptiness == None:
            return None
        empty_index = emptiness.index(1)
        if empty_index == 0:
            self.entries[0].delete(0, END)
            self.entries[0].insert(0, str(self.numerics[2] / self.numerics[1]))
        elif empty_index == 1:
            self.entries[1].delete(0, END)
            self.entries[1].insert(0, str(self.numerics[2] / self.numerics[0]))
        else:
            self.entries[2].delete(0, END)
            self.entries[2].insert(0, str(self.numerics[0] * self.numerics[1]))

    def reset(self):
        for entry in self.entries:
            entry.delete(0, END)


from tkinter import *
root = Tk()
app = App(root)
root.mainloop()

按钮工作正常,但每当我按回车键时,Python就会抱怨:

TypeError: run() takes 1 positional argument but 2 were given

1 个答案:

答案 0 :(得分:3)

使用bind将事件绑定到回调会导致每次调用绑定时都会将事件对象发送到回调。你需要处理这个额外的论点。最简单的方法是使用lambda函数:

root.bind("<Return>", lambda _: self.run())

在上面的代码中,_将成为事件对象。

请注意,您还可以更改run的定义以接受此对象:

def run(self, event):

但我个人更喜欢lambda,因为它更清楚run不使用事件对象。