Change OnScreen Keyboard StringVar (Show linked to one Entry)

Peter Otten __peter__ at web.de
Sun Apr 10 09:18:06 EDT 2016


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))


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /