python: Taking an Tkinter entry value
Change the line:
S1.bind("<Key>", Person.set_attributes('STR', S1.get()) )
to something like:
def key_pressed(event): Person.set_attributes('STR', S1.get())S1.bind("<KeyRelease>", key_pressed)
There are two reasons the original code doesn't work:
bind
takes a function as its second argument- that function is then called when the event occurs. The expressionPerson.set_attributes('STR', S1.get())
as you use it, however, just happens immediately. You need to put that expression into a function so that it happens only when the key is pressed.<Key>
means the event occurs when the key is first pressed, but you would rather it happen when the key is released (and therefore the new character has been added). You thus want to use<KeyRelease>
.
One other note: it would be a good idea to organize all your functionality, especially the callback methods, into a class. For example:
class Window(object): def __init__(self): self.person = Character() self.B = Tk() self.S1 = Entry(B, width = 3) self.S1.grid(row = 0, column = 1) self.S1.bind("<KeyRelease>", self.key_pressed) attrInput("Str: ", 0, 0) self.button = Button(B, text='Quit', command=self.B.destroy).grid(row=3, column=0, sticky=W, pady=4) self.B.mainloop() print self.person.__dict__ def key_pressed(self, event): self.person.set_attributes('STR', self.S1.get())def main(): w = Window()if __name__ == '__main__': main()
The benefit of this organization might not be immediately apparent, but it becomes very useful once you have a large number of callback methods and are keeping track of a large number of widgets.
In response to your comment, you can create both the Entry
and the Label
objects in a for loop, each on its own row. The key_pressed
method can then learn the field and the input text from the event
object that gets passed to it, as seen here (try it):
class Window(object): def __init__(self): self.person = Character() self.B = Tk() self.fields = ["STR", "DEX", "CON", "INT", "WIS", "CHA"] self.inputs = {} for i, f in enumerate(self.fields): self.inputs[f] = Entry(B, width = 3) self.inputs[f].grid(row=i, column=1) self.inputs[f].bind("<KeyRelease>", self.key_pressed) attrInput(f + ":", i, 0) self.button = Button(B, text='Quit', command=self.B.destroy).grid(row=7, column=0, sticky=W, pady=4) self.B.mainloop() print self.person.__dict__ def key_pressed(self, event): field = self.fields[int(event.widget.grid_info()["row"])] self.person.set_attributes(field, event.widget.get())