Search code examples
pythontkinter

Tkinter Combobox dynamically set values


I'm attempting to set the options of a Tkinter Combobox dynamically. My code almost works, and I'm not sure why.

The code is designed to allow typing a string into an Entry box. It then searches through a list for any items that contain that string. So for example, if you type

Mi

into the entry box the list becomes

['Mickey', 'Minnie']

All this works as expected.

The Combobox [values] attribute is supposed to update whenever <FocusIn> is triggered using a function. This does indeed happen, but only after I click on the Combobox twice. I'm not sure why clicking on it the first time doesn't trigger the <FocusIn> binding. Is this the wrong binding? Is there something about my lambda function that isn't quite right? Would love some help!

Code:

from tkinter import *
from tkinter import ttk

init_list = ['Mickey', 'Minnie', 'Donald', 'Pluto', 'Goofy']

def db_values():
    i = inp_var.get()
    db_list = [x for x in init_list if i in x]
    print(db_list)
    return db_list

def db_refresh(event):
    db['values'] = db_values()

root = Tk()
title_label = Label(root, text="Partial string example")
title_label.grid(column=0, row=0)

inp_var = StringVar()
input_box = Entry(root, textvariable=inp_var)
input_box.grid(column=0, row=1)

name_selected = StringVar()
db = ttk.Combobox(root, textvariable=name_selected)
db['values'] = db_values()
db.bind('<FocusIn>', lambda event: db_refresh(event))
db.grid(column=0, row=2, sticky=EW, columnspan=3, padx=5, pady=2)

root.mainloop()

Solution

  • def db_values():
        i = inp_var.get()
        db_list = [x for x in init_list if i in x]
        print(db_list)
        db['values'] = db_values()
    

    Only this small Change is requires. list value must be assigned in the function itself.