Tkinter list box with a search filter

List box with a search filter

Depending on the settings, a list box can be set to allow the user to select only one of the available options or multiple options. If the list is long what often happens if we work with a larger set of data, a filter used to select a few values is a handy addition. Using the filter, you can narrow down the list of values by typing a string of text in the search field above the list. The values that do not match the string are removed from the list. This particular filter needs pressing an ‘enter’ key to start processing the data. In Python Tkinter a list box is represented by Listbox widget.

From programmer’s point of view, we operate on two data list: main_data and filtered_data. We filter the data using str.find(sub[, start[, end]] which returns the lowest index in the string where substring sub is found within the slice s[start:end]. As we always start from the beginning of the string we skip optional arguments start and end which refer to slices of the string. We scan strings from the main_data and copy the finding into filtered_data which is then displayd in our list box. If user removes the filter i.e. deletes all characters from the search box then we restore the original data main_data to the list box.

from tkinter import Tk, Listbox, Entry, StringVar, END, mainloop
 
def cb_search(event):
     
    sstr = search_str.get()
    listbox.delete(0, END)
    # If filter removed show all data
    if sstr == "":
        fill_listbox(main_data) 
        return
 
    filtered_data = list()
    for item in main_data:
        if item.find(sstr) >= 0:
            filtered_data.append(item)
  
    fill_listbox(filtered_data)   
 
def fill_listbox(ld):
    for item in ld:
        listbox.insert(END, item)
 
 
main_data = ["one", "two", "three", "twenty two"]
 
# GUI
master = Tk()
listbox = Listbox(master)
listbox.pack()
fill_listbox(main_data)
 
search_str = StringVar()
search = Entry(master, textvariable=search_str, width=10)
search.pack()
search.bind('<Return>', cb_search)
 
mainloop()

The approach can be also applied to other Tkinter widgets which present data in list or array form e.g. Treeview. The presented code is one of the simplest methods of filtering data in a list box. Firstly, it could be optimised by searching in already filtered data which is displayed in the list box. Secondly, it could be more interactive and the search might be updated after every new keystroke without the need to press the ‘Enter’ button.

4 thoughts on “Tkinter list box with a search filter”

    1. Instead of list_data it should be main_data. I corrected the code. Thank you for your remark.

  1. Can’t you do something to show the results automatically after typing the text?
    Does that mean there is no need to hit enter?

    1. Hi dear friend
      I figured out how to do this myself
      You should use instead of inside bind:
      search.bind(”, cb_search)

Leave a Reply

Your email address will not be published. Required fields are marked *