The following function accepts a list as input and then waits for the user to enter chars in an entry widget. Each time chars are entered, a listbox widget displays all of the items from the input list that include those characters, thus filtering the input list to only selected items. When the user is satisfied with the selected items, he/she clicks the 'ok' button and the function returns an output list, which is a list of items filtered from the input list.
import tkinter as tk
root = tk.Tk()
root.geometry("500x400")
# === PopupFilter Function ====
def PopupFilter(InputList):
OutputList = [] # list of selected items from InputList
def UserTypedCharacter(event): # user typed character in entry box
global OutputList
# get current text in entry box
typed = SearchEntry.get()
OutputList = [] # clear OutputList
for item in InputList: # check entry box text against InputList
if typed.lower() in item.lower():
OutputList.append(item)
SearchListbox.delete(0,tk.END)
SearchListbox.insert(tk.END,*OutputList)
def ExitFunction():
global OutputList
SearchFrame.place_forget() # remove popup from screen
return OutputList # return result
# frame containing widgets for this function
SearchFrame = tk.Frame(root,bg="lightgrey",height=350,width=200)
SearchFrame.place(x=200,y=20)
# entry where user enters characters to filter list
SearchEntry=tk.Entry(SearchFrame,width=30)
SearchEntry.place(x=5,y=30)
SearchEntry.focus() # put cursor in entry box
# Create a binding on the entry box
SearchEntry.bind("<KeyRelease>", UserTypedCharacter)
# listbox displaying filtered items based on chars in entry box
SearchListbox=tk.Listbox(SearchFrame,width=30,height=15)
SearchListbox.place(x=5,y=60)
# button pressed to end the function and return OutputList
OkButton = tk.Button(SearchFrame,text=" OK ")
OkButton.config(command=ExitFunction)
OkButton.place(x=5,y=310)
# === Usage example ===
FruitList = ['pear','peach','plum','mango','apple','banana']
OutputList = PopupFilter(FruitList)
print(OutputList) # this prints immediately, and does not wait for the return statement
# === Root mainloop ===
root.mainloop()
As you can see in the usage example, the issue is that my function returns None immediately. It does not wait for the return keyword. I need to use some sort of loop or other mechanism to keep the function active until the return keyword is used, but I have no idea how to do this. Any help appreciated.