About
AutocompleteEntry is a subclass of Tkinter.Entry that features autocompletion:
Usage
1 entry = AutocompleteEntry(root)
2 entry.set_completion_list(['test','list'])
3
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)
93