Advertisement
here2share

# Tk_autocomplete.py

Oct 22nd, 2020
2,179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.21 KB | None | 0 0
  1. # Tk_autocomplete.py ZZZ
  2.  
  3. from tkinter import *
  4. import re
  5.  
  6. class AutocompleteEntry(Entry):
  7.     def __init__(self, autocompleteList, *args, **kwargs):
  8.  
  9.         # Listbox length
  10.         if 'listboxLength' in kwargs:
  11.             self.listboxLength = kwargs['listboxLength']
  12.             del kwargs['listboxLength']
  13.         else:
  14.             self.listboxLength = 8
  15.  
  16.         # Custom matches function
  17.         if 'matchesFunction' in kwargs:
  18.             self.matchesFunction = kwargs['matchesFunction']
  19.             del kwargs['matchesFunction']
  20.         else:
  21.             def matches(fieldValue, acListEntry):
  22.                 pattern = re.compile('.*' + re.escape(fieldValue) + '.*', re.IGNORECASE)
  23.                 return re.match(pattern, acListEntry)
  24.                
  25.             self.matchesFunction = matches
  26.  
  27.        
  28.         Entry.__init__(self, *args, **kwargs)
  29.         self.focus()
  30.  
  31.         self.autocompleteList = autocompleteList
  32.        
  33.         self.var = self["textvariable"]
  34.         if self.var == '':
  35.             self.var = self["textvariable"] = StringVar()
  36.  
  37.         self.var.trace('w', self.changed)
  38.         self.bind("<Return>", self.selection)
  39.         self.bind("<Up>", self.moveUp)
  40.         self.bind("<Down>", self.moveDown)
  41.        
  42.         self.listboxUp = False
  43.  
  44.     def changed(self, name, index, mode):
  45.         if self.var.get() == '':
  46.             if self.listboxUp:
  47.                 self.listbox.destroy()
  48.                 self.listboxUp = False
  49.         else:
  50.             words = self.comparison()
  51.             if words:
  52.                 self.listboxItems = len(words)
  53.                 if not self.listboxUp:
  54.                     self.listbox = Listbox(width=self["width"], height=self.listboxLength)
  55.                     self.listbox.bind("<Double-Button>", self.selection)
  56.                     self.listbox.bind("<Return>", self.selection)
  57.                     self.listbox.place(x=self.winfo_x(), y=self.winfo_y() + self.winfo_height())
  58.                     self.listboxUp = True
  59.                
  60.                 self.listbox.delete(0, END)
  61.                 for w in words:
  62.                     self.listbox.insert(END,w)
  63.                    
  64.                 self.show_active(0)
  65.                
  66.             else:
  67.                 if self.listboxUp:
  68.                     self.listbox.destroy()
  69.                     self.listboxUp = False
  70.        
  71.     def show_active(self, moveto):
  72.         if self.listboxUp:
  73.             try:
  74.                 index = self.listbox.curselection()[0]
  75.                 self.listbox.selection_clear(first=index)
  76.                 L = self.listboxItems
  77.                 index = str(min(L-1,max(0,int(index)+moveto)))
  78.             except:
  79.                 index = '0'
  80.             self.listbox.selection_set(first=index)
  81.             self.listbox.activate(index)
  82.             self.listbox.see(index) # Scroll!
  83.        
  84.     def selection(self, event):
  85.         if self.listboxUp:
  86.             root.clipboard_clear()
  87.             item = self.listbox.get(ACTIVE)
  88.             self.var.set(item)
  89.             self.listbox.destroy()
  90.             self.listboxUp = False
  91.             self.icursor(END)
  92.             root.clipboard_append(item)
  93.  
  94.     def moveUp(self, event):
  95.         self.show_active(-1)
  96.  
  97.     def moveDown(self, event):
  98.         self.show_active(+1)
  99.  
  100.     def comparison(self):
  101.         return [ w for w in self.autocompleteList if self.matchesFunction(self.var.get(), w) ]
  102.  
  103. autocompleteList = '''
  104. ### SEE pastebin(.)com/pmg0gHuU for this list
  105. '''.splitlines()
  106.  
  107. def matches(fieldValue, acListEntry):
  108.     pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE)
  109.     return re.match(pattern, acListEntry)
  110.  
  111. root = Tk()
  112. ww = root.winfo_screenwidth()
  113. hh = root.winfo_screenheight()
  114. root.geometry("198x690+-3+-3")
  115. entry = AutocompleteEntry(autocompleteList, root, listboxLength=40, width=32, matchesFunction=matches)
  116. entry.grid(row=0, column=0)
  117. Label(text='Tk Auto-Complete').grid(column=0)
  118. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement