title: Python Tkinter Autocomplete combobox with LIKE search?
body: <p>I am trying to populate a Tkinter combobox with pre-defined values to select from. It is populating and I am able to type in and get suggestions. However, in order to do this I have to definitely know the first few characters. If I know some text in the middle or end of the string, its of no use because the combobox does only a <strong>'LIKE%' search and not a '%LIKE%' search</strong>.</p>
  
  <p>Expected Output (Typing the word "Ceramic" fetches all names containing the string. <strong>Note: This is not a Tkinter screenshot</strong>):</p>
  
  <p><a href="https://i.stack.imgur.com/liVgr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/liVgr.png" alt="enter image description here"></a></p>
  
  <p>This is my adaptation of the code till now, if anyone can suggest how to modify the <em>AutocompleteCombobox</em> class to do a LIKE search, it would be great.</p>
  
  <p>The below working piece of code, as an example, has values "Cranberry" and "Strawberry" , my requirement is to type "berry" and get suggestions of both fruits.</p>
  
  <pre><code>import Tkinter
  import ttk
  import sqlite3
  
  
  class AutocompleteCombobox(ttk.Combobox):
  
          def set_completion_list(self, completion_list):
                  """Use our completion list as our drop down selection menu, arrows move through menu."""
                  self._completion_list = sorted(completion_list, key=str.lower) # Work with a sorted list
                  self._hits = []
                  self._hit_index = 0
                  self.position = 0
                  self.bind('&lt;KeyRelease&gt;', self.handle_keyrelease)
                  self['values'] = self._completion_list  # Setup our popup menu
  
          def autocomplete(self, delta=0):
                  """autocomplete the Combobox, delta may be 0/1/-1 to cycle through possible hits"""
                  if delta: # need to delete selection otherwise we would fix the current position
                          self.delete(self.position, Tkinter.END)
                  else: # set position to end so selection starts where textentry ended
                          self.position = len(self.get())
                  # collect hits
                  _hits = []
                  for element in self._completion_list:
                          if element.lower().startswith(self.get().lower()): # Match case insensitively
                                  _hits.append(element)
                  # if we have a new hit list, keep this in mind
                  if _hits != self._hits:
                          self._hit_index = 0
                          self._hits=_hits
                  # only allow cycling if we are in a known hit list
                  if _hits == self._hits and self._hits:
                          self._hit_index = (self._hit_index + delta) % len(self._hits)
                  # now finally perform the auto completion
                  if self._hits:
                          self.delete(0,Tkinter.END)
                          self.insert(0,self._hits[self._hit_index])
                          self.select_range(self.position,Tkinter.END)
  
          def handle_keyrelease(self, event):
                  """event handler for the keyrelease event on this widget"""
                  if event.keysym == "BackSpace":
                          self.delete(self.index(Tkinter.INSERT), Tkinter.END)
                          self.position = self.index(Tkinter.END)
                  if event.keysym == "Left":
                          if self.position &lt; self.index(Tkinter.END): # delete the selection
                                  self.delete(self.position, Tkinter.END)
                          else:
                                  self.position = self.position-1 # delete one character
                                  self.delete(self.position, Tkinter.END)
                  if event.keysym == "Right":
                          self.position = self.index(Tkinter.END) # go to end (no selection)
                  if len(event.keysym) == 1:
                          self.autocomplete()
                  # No need for up/down, we'll jump to the popup
                  # list at the position of the autocompletion
  
  
  def test(test_list):
          """Run a mini application to test the AutocompleteEntry Widget."""
          root = Tkinter.Tk(className='AutocompleteCombobox')
  
          combo = AutocompleteCombobox(root)
          combo.set_completion_list(test_list)
          combo.pack()
          combo.focus_set()
          # I used a tiling WM with no controls, added a shortcut to quit
          root.bind('&lt;Control-Q&gt;', lambda event=None: root.destroy())
          root.bind('&lt;Control-q&gt;', lambda event=None: root.destroy())
          root.mainloop()
  
  if __name__ == '__main__':
          test_list = ('apple', 'banana', 'Cranberry', 'dogwood', 'alpha', 'Acorn', 'Anise', 'Strawberry' )
          test(test_list)
  </code></pre>