468,104 Members | 1,316 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,104 developers. It's quick & easy.

ghost chars in Tkinter.Entry

Strider1066
Is it a bug or a feature?

I'm trying to sub-class an Entry widget that displays a template (i.e. '____-__-__') for users and does keystroke validation. It is starting to work but with one problem. Every key is echoed in the Entry widget. If I were to type a '2', '22__-__-__' is displayed. The next entry replaces the first duplicate with another, that is if I were to then type a '3' the display now shows '233__-__-__', and so on. The correct data is held by the widget as shown by a entry.get() but the display is wrong.

I have started poking at the code with a sharp stick, Please, any suggestions.

steve

Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2. import pdb
  3.  
  4. class entryDate(Entry):
  5.     def __init__(self, parent=None, template="@2###@-##@-##"):
  6.         Entry.__init__(self, parent)
  7.         self.ptr=-1                 # '-1' to accomadate nextwriteable's ptr +=mov
  8.         self.next=object        #for linked list
  9.         self.prior=object       #for linked list
  10.         self.refrList=self.makeReferenceList(template)
  11.         self.workingList=self.makeWorkingList(self.refrList)
  12.         self.bind('<Key>', self.onKeyPress)
  13.         self.config(self, background = "green", width = 10) 
  14.         self.insert(0, (''.join(self.workingList)))
  15.         self.nextWriteable(1)
  16.  
  17.     def makeReferenceList(self, templateStr):
  18.         ts = templateStr
  19.         tl=[]
  20.         i=0
  21.         while i < len(ts):
  22.             if ts[i]=='@':
  23.                 tl.append(ts[i:i+2])
  24.                 i += 2
  25.             else:
  26.                 tl.append(ts[i : i +1])
  27.                 i+=1
  28.         return tl
  29.  
  30.     def makeWorkingList(self, tmplt):
  31.         s=[]
  32.         displayChar = '_'
  33.         for itm in tmplt:
  34.             if itm[0]=='@':
  35.                 s.append(itm[1])
  36.             else:
  37.                 s.append(displayChar)
  38.         return s
  39.  
  40.     def onKeyPress(self, event):
  41.         if event.char==event.keysym: #normal key
  42.             self.delete(0, END)
  43.             if self.refrList[self.ptr]=='#': #ie writeable
  44.                 if event.char.isdigit():
  45.                     self.workingList[self.ptr]=event.char
  46.                     self.insert(0, (''.join(self.workingList)))
  47.                     self.nextWriteable(1)
  48.                 else:                                   # if alpha key
  49.                     s = ''.join(self.workingList)
  50.                     self.insert( 0, (''.join(self.workingList)))
  51.         elif len(event.char)==1:        # punctuation
  52.             pass
  53.         else:
  54.             pass
  55.  
  56.     def nextWriteable(self, mov):
  57.         self.ptr += mov
  58.         if self.ptr < 0:
  59.             self.ptr=len(self.refList)   #replace with linked list
  60.             self.icursor=self.ptr           # ''
  61.             self.prior.focus_set()
  62.         elif self.ptr == len(self.refrList):
  63.             self.ptr=0                    #replace with linked list
  64.             self.icursor=0                # ''
  65.         elif self.refrList[self.ptr][0]=='@':
  66.             self.nextWriteable(mov)
  67.         else:
  68.             self.icursor(self.ptr)
  69.  
  70. if __name__=='__main__':
  71.     root = Tk()
  72.     entr= entryDate(root)
  73.     entr.pack()
  74.     entr.focus_set()
  75.     root.mainloop()
Mar 14 '08 #1
2 1428
jlm699
314 100+
The problem here is that while you have binded the keypress event to your function onKeyPress, it is an instance binding only, Tkinter is still performing its own keypress event at the root level. Remove the binding from your class's __init__ and place it after the line as such:
Expand|Select|Wrap|Line Numbers
  1. if __name__=='__main__':
  2.     root = Tk()
  3.     entr= entryDate(root)
  4.     root.bind('<Key>',entr.onKeyPress)
  5.     entr.pack()
  6.     entr.focus_set()
  7.     root.mainloop()
Mar 14 '08 #2
Thank you,
That worked like a champ.
Mar 15 '08 #3

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

1 post views Thread by Thomas Nücker | last post: by
reply views Thread by phil | last post: by
1 post views Thread by phil | last post: by
3 posts views Thread by Matt Hammond | last post: by
2 posts views Thread by Martyn Quick | last post: by
1 post views Thread by Michael Yanowitz | last post: by
1 post views Thread by C Martin | last post: by
2 posts views Thread by skanemupp | last post: by
reply views Thread by Leonhard Vogt | last post: by
1 post views Thread by Solo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.