By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,715 Members | 748 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,715 IT Pros & Developers. It's quick & easy.

How do i set a limit in an Entry widget

P: 17
Hi,

I have an Entry widget where in i can enter string.

Clarifications needed:

1. The user should not be able to exceed 15 characters at the max in the Entry widget. How do i set the limit for the same.

2. The user should not be able to enter "SPACE". Is there any such provisions for the same?

Can the same be done in Text widget?
Nov 28 '06 #1
Share this Question
Share on Google+
1 Reply


bartonc
Expert 5K+
P: 6,596
I wrote these classes (sub classes of tkinter.entry). The do all kinds of validation. You can use these a base for your own subclasses.
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2. from dbtools import *
  3. from datetime import date, time
  4. from calendar import monthrange
  5.  
  6. ### I tried using Tk's validatecommand callback, but it works badly.
  7. ### Access and choice of event bindings is much better this way.
  8. ### The creation of the set() method make these widgets looks like Variables.
  9.  
  10. class ValidEntry(Entry):
  11.     """Validate the value of an entry widget; Use escape to go back to
  12.     previous value.
  13.     A callback routine which expects the event
  14.     can optionally be notified of changes to the entry. Set next to
  15.     a widget instance that whould get the focus next on <Return>."""
  16.     def __init__(self, master=None, callback=None, minvalue=None, maxvalue=None,
  17.                  cnf={}, **kw):
  18.         try:
  19.             self.next = kw.pop('next')
  20.         except KeyError:
  21.             self.next = None
  22.         try:
  23.             self.receiver = kw.pop('receiver')
  24.         except KeyError:
  25.             self.receiver = None
  26.         try:
  27.             self.nullProc = kw.pop('nullProc')
  28.         except KeyError:
  29.             self.nullProc = None
  30.         Entry.__init__(self, master, cnf, **kw)
  31.  
  32.         self.callback = callback
  33.         self.minvalue = minvalue
  34.         self.maxvalue = maxvalue
  35.         self.oldvalue = ''
  36.  
  37.         self.bind('<Tab>', self.CheckValue)
  38.         self.bind('<Return>', self.CheckValue)
  39.         self.bind('<FocusOut>', self.CheckValue)    # For clicks outside this widget
  40.         self.bind('<FocusIn>', self.ReFocus)
  41.         self.bind('<Escape>', self.UndoValue)
  42.  
  43.     def set(self, value):
  44.         self.delete(0,END)
  45.         self.insert(0, str(value))
  46.         self.oldvalue = str(value)
  47.  
  48.     def replace(self, value):
  49. ##        print 'replacing %s with %s' %(repr(self.oldvalue), repr(value))
  50.         if self.oldvalue:
  51.             self.oldvalue = ''
  52.         self.delete(0,END)
  53.         self.insert(0, str(value))
  54.  
  55.     def clear(self):
  56.         self.set('')
  57.  
  58.     def convert(self, value=None):
  59.         """Override this method to return an alternate format (or type)"""
  60.         if value is None:
  61.             value = self.get()
  62.         return value
  63.  
  64.     def CheckValue(self, event=None):
  65.         """If the current value is equal to oldvalue, there's nothing to
  66.            check.  Else, validate() may change the the user-entered value,
  67.            so re-get() and store in oldvalue. Callbacks happen for new valid
  68.            values. Events are generated for old values and new valid values."""
  69.         if event is None:
  70.             event = Event()
  71.             event.widget = self
  72.             event.type = '35'
  73. ##        print 'checking %s' %event.widget
  74.         value = self.get()
  75.         isvalid = True
  76.         if value != self.oldvalue:
  77.             if value:
  78.                 isvalid = self.Validate(value)
  79.             if isvalid:
  80.                 if type(isvalid) == bool:
  81.                     newvalue = self.get()
  82.                     self.oldvalue = newvalue
  83.                     self.select_clear()
  84.                     self.icursor(END)
  85.                     if self.callback is not None:
  86. ##                        print 'calling back'
  87.                         self.callback(event)
  88.                 else: self.Invalid(isvalid[0], isvalid[1])
  89.             else:
  90.                 self.Invalid()
  91.         else:
  92.             self.SendEvent(event)
  93.         if isvalid:
  94.             if event.type == '2' or event.type == '35':
  95.                 if self.next is not None:
  96.                     self.next.focus_set()
  97.  
  98.     def Invalid(self, index1=0, index2=END):
  99.         self.bell()
  100.         self.focus_set()
  101.         self.select_range(index1, index2)
  102.         self.icursor(index1)
  103.  
  104.     def Validate(self, value):
  105.         """An override of this method may re-format the string
  106.         and then store it by calling self.replace(newvalue).
  107.         Call this method from inside a try block that catches the
  108.         ValueError exception for min/max checking after converting
  109.         the string to a hashable type"""
  110.  
  111.         minvalue = self.minvalue
  112.         if minvalue is not None and value < minvalue:
  113.             raise ValueError
  114.         maxvalue = self.maxvalue
  115.         if maxvalue is not None and value > maxvalue:
  116.             raise ValueError
  117.         return True
  118.  
  119.     def ReFocus(self, event=None):
  120.         self.select_range(0, END)
  121.         self.icursor(END)
  122.  
  123.     def UndoValue(self, event=None):
  124.         """Pass the <Escape> to the receiver."""
  125.         self.set(self.oldvalue)
  126.         self.ReFocus()
  127.         try:
  128.             self.receiver.event_generate("<<Entry_Escape>>")
  129.         except AttributeError: pass
  130.  
  131.     def ReturnEvent(self):
  132.         """Generate a <Return> event in this widget."""
  133.         event = Event()
  134.         event.widget = self
  135.         event.type = '2'
  136.         self.icursor(END)
  137.         self.CheckValue(event)
  138.  
  139.     def SendEvent(self, event):
  140.         """Pass the <Tab>, <Return>, <FocusOut> up the chain when
  141.            the value didn't change."""
  142.         try:
  143.             self.nullProc(event)
  144.         except TypeError: pass
  145.  
  146.     def SetNextWidget(self, nextWidget):
  147.         self.next = nextWidget
  148.  
  149.     def GetNextWidget(self):
  150.         return self.next
  151.  
  152.     def SetRecWidget(self, receiver):
  153.         self.receiver = receiver
  154.  
  155.     def SetNullProc(self, nullProc):
  156.         self.nullProc = nullProc
  157.  
  158.     def SetCallback(self, callback):
  159.         self.callback = callback
  160.  
  161.     def Close(self):
  162.         self.ReturnEvent()
  163.  
  164. class IntegerEntry(ValidEntry):
  165.     def Validate(self, value):
  166.         try:
  167.             a = int(value)
  168.             ValidEntry.Validate(self, a)
  169.             return True
  170.         except ValueError:
  171.             return False
  172.  
  173.     def convert(self, value=None):
  174.         if value is None:
  175.             value = self.get()
  176.         try:
  177.             value = int(value)
  178.         except ValueError:
  179.             pass
  180.         return value
  181.  
  182. class FloatEntry(ValidEntry):
  183.     def Validate(self, value):
  184.         try:
  185.             a = float(value)
  186.             ValidEntry.Validate(self, a)
  187.             return True
  188.         except ValueError:
  189.             return False
  190.  
  191.     def convert(self, value=None):
  192.         if value is None:
  193.             value = self.get()
  194.         try:
  195.             value = float(value)
  196.         except ValueError:
  197.             pass
  198.         return value
  199.  
  200. class HexEntry(ValidEntry):
  201.     def Validate(self, value):
  202.         try:
  203.             a = int(value, 16)
  204.             ValidEntry.Validate(self, a)
  205.             self.replace(value.upper())
  206.             return True
  207.         except ValueError:
  208.             return False
  209.  
  210. class StringEntry(ValidEntry):
  211.     """Disable minvalue and maxvalue, allow all text."""
  212.     def Validate(self, value):
  213.         return True
  214.  
  215. class StateEntry(ValidEntry):
  216.     def Validate(self, value):
  217.         if len(value) > 2 or not value.isalpha():
  218.             return False
  219.         self.replace(value.upper())
  220.         return True
  221.  
  222. class NameEntry(ValidEntry):
  223.     def Validate(self, value):
  224.         l = value.split()
  225.         value = ' '.join(value.capitalize() for value in l)
  226.         self.replace(value)
  227.         return True
  228.  
  229. class PhoneEntry(ValidEntry):
  230.     def Validate(self, value):
  231.         for char in set(' -()').intersection(value):
  232.             l = value.split(char)
  233.             value = ''.join(l)
  234.         i = len(value)
  235.         if i >= 7:
  236.             if i == 7 and int(value[0]) > 1:
  237.                 self.replace('%s-%s' %(value[:3], value[3:]))
  238.                 return True
  239.             if i == 8 and value[0] == '1':
  240.                 self.replace('1-%s-%s' %(value[1:4], value[4:]))
  241.                 return True
  242.             if i == 10 and int(value[0]) > 1:
  243.                 self.replace('(%s) %s-%s' %(value[:3], value[3:6], value[6:]))
  244.                 return True
  245.             if i == 11 and value[0] == '1':
  246.                 self.replace('1-(%s) %s-%s' %(value[1:4], value[4:7], value[7:]))
  247.                 return True
  248.         return False
  249.  
  250.  
  251.  
  252. if __name__ == '__main__':
  253.     root = Tk(className='widget test window')
  254.     top = Frame()
  255.     top.pack()
  256.  
  257.     def cb(event):
  258.         print 'Callback called by event type %s' %(event.type)
  259.  
  260.     de = DateEntry(top, width=11, callback=cb)
  261.     pe = PhoneEntry(top, width=15, callback=cb)
  262.     ne = TimeEntry(top, callback=cb)
  263.  
  264.     de.next = pe
  265.     pe.next = ne
  266.     ne.next = de
  267.  
  268.     de.pack()
  269.     pe.pack()
  270.     ne.pack()
  271.     de.setdate('')
  272.     root.mainloop()
Nov 28 '06 #2

Post your reply

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