2

I am attempting to bind a function to multiple Entry widgets in Tkinter. I populated my frame with many Entry widgets in a for loop. To bind a function to an Entry widget that was created using a for loop, I thought I could do something like the following:

import Tkinter as tk   

class Application(tk.Frame):
    def __init__(self, master):
        self.master = master
        tk.Frame.__init__(self, master, width=200, height=200)
        self.master.title('Application')
        self.pack_propagate(0)
        self.pack()

        for i in range(10):
            strVar = tk.StringVar()
            item = tk.Entry(self, textvariable=strVar)
            item.bind(sequence='<Return>', func=lambda strVar=strVar, i=i: self.obtain(i, strVar))
            item.grid(row=i, sticky=tk.W)

    def obtain(self, i, strVar):
        print i
        print strVar.get()

    def run(self):
        self.mainloop()

app = Application(tk.Tk())
app.run()

But I am obtaining the following error:

print strVar.get()
AttributeError: Event instance has no attribute 'get'

I don't understand why it can't interpret strVar as a tk.StringVar() variable...Any ideas?

Cœur
  • 37,241
  • 25
  • 195
  • 267
KidSudi
  • 460
  • 2
  • 7
  • 19
  • This problem actually has nothing to do with the `for` loop, though there is another common problem that does (carefully avoided here). – Karl Knechtel Aug 14 '22 at 21:20

1 Answers1

3

The Event is passed as the first argument to your callback. Since your callback's first argument is strVar, the Event object is being passed in that variable. You should add an additionl argument at the front of your argument list to hold the event, e.g., lambda event, strVar=strVar, i=i: self.obtain(i, strVar).

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • Ah, very nice it works! I just don't understand the Event object. Why don't I have to do this for the Checkbutton widget? – KidSudi Mar 13 '14 at 19:05
  • @KidSudi: I don't see any checkbutton widget in your example. – BrenBarn Mar 13 '14 at 19:06
  • i.e. I did a similar thing with Checkbuttons, made the command = lambda strVar=strVar, i=i, etc. There is no need for the Event object in that case. – KidSudi Mar 13 '14 at 19:07
  • The example is here: http://stackoverflow.com/questions/21449176/issue-with-generating-ttk-checkboxes-in-loops-and-passing-arguments – KidSudi Mar 13 '14 at 19:08
  • @KidSudi -- "There is no need for the Event object" -- How do you know? Maybe someone will come up with a need. And, even if they don't, coding around a special case is more difficult than keeping it the same as the rest of the API. – mgilson Mar 13 '14 at 19:10
  • I just wanted to know why I get an error when not passing an Event object to an Entry function, but don't get an error when not passing an Event object to a Checkbutton function. – KidSudi Mar 13 '14 at 19:14
  • @KidSudi: That code is a bit long and confusing, but if I understand right, the event object is being passed in that case as well. The difference is that in your Checkbutton event handler, all you do with that argument is print it, so it works anyway. – BrenBarn Mar 13 '14 at 19:18