About

AutocompleteEntry is a subclass of Tkinter.Entry that features autocompletion:

autocomplete-widget.png

Usage

   1 entry = AutocompleteEntry(root)
   2 entry.set_completion_list(['test','list'])

Code

   1 #!/usr/bin/env python
   2 # encoding: utf-8
   3 """
   4 tkentrycomplete.py
   5 
   6 A tkinter widget that features autocompletion.
   7 
   8 Created by Mitja Martini on 2008-11-29.
   9 """
  10 import sys
  11 import os
  12 import Tkinter
  13 
  14 __version__ = "1.0"
  15 
  16 tkinter_umlauts=['odiaeresis', 'adiaeresis', 'udiaeresis', 'Odiaeresis', 'Adiaeresis', 'Udiaeresis', 'ssharp']
  17 
  18 class AutocompleteEntry(Tkinter.Entry):
  19         """
  20         Subclass of Tkinter.Entry that features autocompletion.
  21         
  22         To enable autocompletion use set_completion_list(list) to define 
  23         a list of possible strings to hit.
  24         To cycle through hits use down and up arrow keys.
  25         """
  26         def set_completion_list(self, completion_list):
  27                 self._completion_list = completion_list
  28                 self._hits = []
  29                 self._hit_index = 0
  30                 self.position = 0
  31                 self.bind('<KeyRelease>', self.handle_keyrelease)               
  32 
  33         def autocomplete(self, delta=0):
  34                 """autocomplete the Entry, delta may be 0/1/-1 to cycle through possible hits"""
  35                 if delta: # need to delete selection otherwise we would fix the current position
  36                         self.delete(self.position, Tkinter.END)
  37                 else: # set position to end so selection starts where textentry ended
  38                         self.position = len(self.get())
  39                 # collect hits
  40                 _hits = []
  41                 for element in self._completion_list:
  42                         if element.startswith(self.get().lower()):
  43                                 _hits.append(element)
  44                 # if we have a new hit list, keep this in mind
  45                 if _hits != self._hits:
  46                         self._hit_index = 0
  47                         self._hits=_hits
  48                 # only allow cycling if we are in a known hit list
  49                 if _hits == self._hits and self._hits:
  50                         self._hit_index = (self._hit_index + delta) % len(self._hits)
  51                 # now finally perform the auto completion
  52                 if self._hits:
  53                         self.delete(0,Tkinter.END)
  54                         self.insert(0,self._hits[self._hit_index])
  55                         self.select_range(self.position,Tkinter.END)
  56                         
  57         def handle_keyrelease(self, event):
  58                 """event handler for the keyrelease event on this widget"""
  59                 if event.keysym == "BackSpace":
  60                         self.delete(self.index(Tkinter.INSERT), Tkinter.END) 
  61                         self.position = self.index(Tkinter.END)
  62                 if event.keysym == "Left":
  63                         if self.position < self.index(Tkinter.END): # delete the selection
  64                                 self.delete(self.position, Tkinter.END)
  65                         else:
  66                                 self.position = self.position-1 # delete one character
  67                                 self.delete(self.position, Tkinter.END)
  68                 if event.keysym == "Right":
  69                         self.position = self.index(Tkinter.END) # go to end (no selection)
  70                 if event.keysym == "Down":
  71                         self.autocomplete(1) # cycle to next hit
  72                 if event.keysym == "Up":
  73                         self.autocomplete(-1) # cycle to previous hit
  74                 # perform normal autocomplete if event is a single key or an umlaut
  75                 if len(event.keysym) == 1 or event.keysym in tkinter_umlauts:
  76                         self.autocomplete()
  77 
  78 def test(test_list):
  79         """Run a mini application to test the AutocompleteEntry Widget."""
  80         root = Tkinter.Tk(className=' AutocompleteEntry demo')
  81         entry = AutocompleteEntry(root)
  82         entry.set_completion_list(test_list)
  83         entry.pack()
  84         entry.focus_set()
  85         root.mainloop()
  86 
  87 if __name__ == '__main__':
  88         test_list = (u'test', u'type', u'true', u'tree', u'tölz')
  89         print u"Type a 't' to test the AutocompleteEntry widget."
  90         print u"Will use AutocompleteEntry.set_completion_list(%s)" % unicode(test_list)
  91         print u"Try also the backspace key and the arrow keys."
  92         test(test_list)

tkinter: AutocompleteEntry (last edited 2010-07-26 11:59:12 by localhost)