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