Diego Lelis wrote: > Hi guys, im having a little problem to make the StringVar Linked to my > OnScreen Keyboard Change when the user click in one Entry. > > Here's my code: > from tkinter import * > > ____________________________Begin > Code_______________________________________ > > def frame(root, side): > w = Frame(root) > w.pack(side=side, expand=YES, fill=BOTH) > return w > > def button(root, side, text, command=None): > w = Button(root, text=text, command=command) > w.pack(side=side, expand=YES, fill=BOTH) > return w > > > class Keyboard(Frame): > def __init__(self): > Frame.__init__(self) > self.option_add('*Font', 'Verdana 12 bold') > self.pack(expand=YES, fill=BOTH) > self.master.title('Simple Screen Keyboard') > > def detect_Focus(event): > print ('Change selected_display to the display correspondent > to selected entry') > > display_1 = StringVar() > entry_1 = Entry(self, relief=SUNKEN, textvariable=display_1) > entry_1.bind('<FocusIn>', detect_Focus) > entry_1.pack(side=TOP, expand=YES, fill=BOTH) > > > display_2 = StringVar() > entry_2 = Entry(self, relief=SUNKEN, textvariable=display_2) > entry_2.bind('<FocusIn>', detect_Focus) > entry_2.pack(side=TOP, expand=YES, fill=BOTH) > > selected_display = display_1 > > for key in ("123", "456", "789", "-0."): > keyF = frame(self, TOP) > for char in key: > button(keyF, LEFT, char, > lambda w=selected_display, c=char: w.set(w.get() + > c)) > > if __name__ == '__main__': > Keyboard().mainloop() > > > ____________________________End > Code_______________________________________ > > > When i run the detect_Focus Function, i wanted change the > selected_display, to make the user change the entry2(display_2), using my > on screen keyboard.
The problem is that by setting the default for w > button(keyF, LEFT, char, > lambda w=selected_display, c=char: w.set(w.get() + > c)) you bind w to the current selected display, and to change that binding afterwards is messy. Instead you should use a variable in a scope shared by detect_Focus() and the lambda. If there is only ever one instance of Keyboard this could be the global scope, but using a function or a helper class if better. Here's the lazy approach that uses the scope of the __init__() method: class Keyboard(Frame): def __init__(self): Frame.__init__(self) self.option_add('*Font', 'Verdana 12 bold') self.pack(expand=YES, fill=BOTH) self.master.title('Simple Screen Keyboard') def detect_Focus(event): nonlocal display print ('Change selected_display to the display correspondent to selected entry') display = display_2 if display is display_1 else display_1 display_1 = StringVar() entry_1 = Entry(self, relief=SUNKEN, textvariable=display_1) entry_1.bind('<FocusIn>', detect_Focus) entry_1.pack(side=TOP, expand=YES, fill=BOTH) display_2 = StringVar() entry_2 = Entry(self, relief=SUNKEN, textvariable=display_2) entry_2.bind('<FocusIn>', detect_Focus) entry_2.pack(side=TOP, expand=YES, fill=BOTH) display = display_1 for key in ("123", "456", "789", "-0."): keyF = frame(self, TOP) for char in key: button(keyF, LEFT, char, lambda c=char: display.set(display.get() + c)) -- https://mail.python.org/mailman/listinfo/python-list