Search code examples
pythontkintertkinter-entry

Errors when using entry widgets Tkinter


I am attempting to create a GUI that will convert metric measurements to Imperial or the other way round. However I am having trouble getting the variable from the Entry widget. My exact error is:

Exception in Tkinter callback Traceback (most recent call last): File "C:\Python32\lib\tkinter__init__.py", line 1399, in __call__ return self.func(*args) TypeError: valid() takes exactly 1 positional argument (2 given)

I have attempted using the textvariable method however I got much of the same error. I am kind of new to this, so I am not sure what's wrong here. Help would be appreciated.

from tkinter import *

root = Tk()
class Buttons:
    def __init__(self,master,ImperialText,MetricText,metricVal):
        self.ImperialText = ImperialText
        self.MetricText = MetricText



        self.master = master
        self.Text1 = (ImperialText +'-'+ MetricText)
        self.button = Button(self.master,text= self.Text1,command = self.calc)
        self.button.grid(column = 0)
        self.button.config(height= 3,width=30)

    def calc(self):
        self.EntryStr = None
        self.entry = Entry(self.master)
        self.label = Label(self.master,text = 'Enter '+self.ImperialText)

        self.entry.grid(column = 1,row = 1)
        self.label.grid(column = 1,row = 0)

        self.entry.bind('<Return>',self.valid)

    def valid(self):
        print (str(self.entry.get()))

button1 = Buttons(root,'inches','centimetres',2.54)
button2 = Buttons(root,'miles','kilometres',1.6093)
button3 = Buttons(root,'foot','metres',0.3048)
button4 = Buttons(root,'yards','metres',0.9144)
button5 = Buttons(root,'gallons','litres',4.546)
button6 = Buttons(root,'pounds','kilograms',0.454)
button7 = Buttons(root,'ounces','grams',0.454)

root.mainloop()

Solution

  • When you bind a function, tkinter always passes in an object that represents the event.

    Change valid to be like this:

        def valid(self, event):
            print (str(self.entry.get()))
    

    If you bind multiple widgets to the same function, the widget that received the event is event.widget. So, for example, you could rewrite your code like this to make it more reusable:

    def valid(self, event):
        print(event.widget.get())
    

    Additional documentation and examples for the bind method can be found here: