Search code examples
pythontkintercomboboxradio-buttontk-toolkit

implement "combobox with like search" inside class Tk


I have the following code:


import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

from FUNCTIONS import unique_languages, unique_systems, unique_products, unique_business

from FUNCTIONS import product_summary, product_match, system_summary, system_match, language_summary, business_summary, \
    business_match


class App(tk.Tk):
    """Application start here"""

    def __init__(self):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.on_close)
        self.title("Simple App")

        self.option = tk.IntVar()
        self.departments = ('product_summary', 'product_match',
                            'system_summary', 'system_match',
                            'business_summary', 'business_match',
                            'language_summary')
        self.df_MA_1 = unique_products
        self.df_MA_2 = unique_products
        self.df_MA_3 = unique_systems
        self.df_MA_4 = unique_systems
        self.df_MA_5 = unique_business
        self.df_MA_6 = unique_business
        self.df_MA_7 = unique_languages

        self.init_ui()
        self.on_reset()

    def init_ui(self):

        w = ttk.Frame(self, padding=8)

        r = 0
        c = 1
        ttk.Label(w, text="Combobox:").grid(row=r, sticky=tk.W)
        self.cbCombo = ttk.Combobox(w, values="")
        self.cbCombo.grid(row=r, column=c, padx=5, pady=5)

        r += 1
        ttk.Label(w, text="Radiobutton:").grid(row=r, sticky=tk.W)
        for index, text in enumerate(self.departments):
            ttk.Radiobutton(w,
                            text=text,
                            variable=self.option,
                            value=index,
                            command=self.set_combo_values).grid(row=r,
                                                                column=c,
                                                                sticky=tk.W,
                                                                padx=5, pady=5)
            r += 1

        r = 0
        c = 2

        b = ttk.LabelFrame(self, text="", relief=tk.GROOVE, padding=5)

        bts = [("Reset", 0, self.on_reset, "<Alt-r>"),
               ("Close", 0, self.on_close, "<Alt-c>")]

        for btn in bts:
            ttk.Button(b, text=btn[0], underline=btn[1], command=btn[2]).grid(row=r,
                                                                              column=c,
                                                                              sticky=tk.N + tk.W + tk.E,
                                                                              padx=5, pady=5)
            self.bind(btn[3], btn[2])
            r += 1

        b.grid(row=0, column=1, sticky=tk.N + tk.W + tk.S + tk.E)
        w.grid(row=0, column=0, sticky=tk.N + tk.W + tk.S + tk.E)

    def set_combo_values(self):

        print("you have selected {0} radio option".format(self.option.get()))

        self.cbCombo.set("")

        if self.option.get() == 0:
            self.cbCombo["values"] = self.df_MA_1
        elif self.option.get() == 1:
            self.cbCombo["values"] = self.df_MA_2
        elif self.option.get() == 2:
            self.cbCombo["values"] = self.df_MA_3
        elif self.option.get() == 3:
            self.cbCombo["values"] = self.df_MA_4
        elif self.option.get() == 4:
            self.cbCombo["values"] = self.df_MA_5
        elif self.option.get() == 5:
            self.cbCombo["values"] = self.df_MA_6
        elif self.option.get() == 6:
            self.cbCombo["values"] = self.df_MA_7

    def on_reset(self, evt=None):
        self.cbCombo.set("")
        self.option.set(0)
        self.set_combo_values()

    def on_close(self, evt=None):
        """Close all"""
        if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
            self.destroy()


def main():
    app = App()
    app.mainloop()


if __name__ == '__main__':
    main()


I need to implement the code inside the class https://stackoverflow.com/a/65821591/12759374 Exactly this function:


def check_input(event):
    value = event.widget.get()

    if value == '':
        combo_box['values'] = lst
    else:
        data = []
        for item in lst:
            if value.lower() in item.lower():
                data.append(item)

        combo_box['values'] = data

and this execution:


combo_box.bind('<KeyRelease>', check_input)

How to union these two solutions? So, I have 7 RadioButtons, dropdown lists based on selected RadioButtons, but I have 1 list where more than 300 elements, so I want to realize to search function inside given dropdown list.


Solution

  • I did it, thank you!

    
    import tkinter as tk
    from tkinter import ttk
    from tkinter import messagebox
    
    from FUNCTIONS import unique_languages, unique_systems, unique_products, unique_business
    
    from FUNCTIONS import product_summary, product_match, system_summary, system_match, language_summary, business_summary, \
        business_match
    
    
    class App(tk.Tk):
        """Application start here"""
    
        def __init__(self):
            super().__init__()
    
            self.protocol("WM_DELETE_WINDOW", self.on_close)
            self.title("Simple App")
    
            self.option = tk.IntVar()
            self.departments = ('product_summary', 'product_match',
                                'system_summary', 'system_match',
                                'business_summary', 'business_match',
                                'language_summary')
            self.df_MA_1 = unique_products
            self.df_MA_2 = unique_products
            self.df_MA_3 = unique_systems
            self.df_MA_4 = unique_systems
            self.df_MA_5 = unique_business
            self.df_MA_6 = unique_business
            self.df_MA_7 = unique_languages
    
            self.init_ui()
            self.on_reset()
    
        def init_ui(self):
    
            w = ttk.Frame(self, padding=8)
    
            r = 0
            c = 1
            ttk.Label(w, text="Combobox:").grid(row=r, sticky=tk.W)
            self.cbCombo = ttk.Combobox(w, values="")
            self.cbCombo.grid(row=r, column=c, padx=5, pady=5)
    
            r += 1
            ttk.Label(w, text="Radiobutton:").grid(row=r, sticky=tk.W)
            for index, text in enumerate(self.departments):
                ttk.Radiobutton(w,
                                text=text,
                                variable=self.option,
                                value=index,
                                command=self.set_combo_values).grid(row=r,
                                                                    column=c,
                                                                    sticky=tk.W,
                                                                    padx=5, pady=5)
                r += 1
    
            r = 0
            c = 2
    
            b = ttk.LabelFrame(self, text="", relief=tk.GROOVE, padding=5)
    
            bts = [("Reset", 0, self.on_reset, "<Alt-r>"),
                   ("Close", 0, self.on_close, "<Alt-c>")]
    
            for btn in bts:
                ttk.Button(b, text=btn[0], underline=btn[1], command=btn[2]).grid(row=r,
                                                                                  column=c,
                                                                                  sticky=tk.N + tk.W + tk.E,
                                                                                  padx=5, pady=5)
                self.bind(btn[3], btn[2])
                r += 1
    
            b.grid(row=0, column=1, sticky=tk.N + tk.W + tk.S + tk.E)
            w.grid(row=0, column=0, sticky=tk.N + tk.W + tk.S + tk.E)
    
            self.bind("<<ComboboxSelected>>", self.selection)
            self.bind('<KeyRelease>', self.check_input)
    
        def set_combo_values(self):
    
            print("you have selected {0} radio option".format(self.option.get()))
    
            self.cbCombo.set("")
    
            if self.option.get() == 0:
                self.cbCombo["values"] = self.df_MA_1
                self.chosen = self.df_MA_1
            elif self.option.get() == 1:
                self.cbCombo["values"] = self.df_MA_2
                self.chosen = self.df_MA_2
            elif self.option.get() == 2:
                self.cbCombo["values"] = self.df_MA_3
                self.chosen = self.df_MA_3
            elif self.option.get() == 3:
                self.cbCombo["values"] = self.df_MA_4
                self.chosen = self.df_MA_4
            elif self.option.get() == 4:
                self.cbCombo["values"] = self.df_MA_5
                self.chosen = self.df_MA_5
            elif self.option.get() == 5:
                self.cbCombo["values"] = self.df_MA_6
                self.chosen = self.df_MA_6
            elif self.option.get() == 6:
                self.cbCombo["values"] = self.df_MA_7
                self.chosen = self.df_MA_7
    
        def on_reset(self, evt=None):
            self.cbCombo.set("")
            self.option.set(0)
            self.set_combo_values()
    
        def on_close(self, evt=None):
            """Close all"""
            if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
                self.destroy()
    
        def selection(self, event):
            self.var_Selected = self.cbCombo.get()
            print(self.var_Selected)
    
        def check_input(self, event):
            value = event.widget.get()
    
            if value == '':
                self.cbCombo['values'] = self.chosen
            else:
                data = []
                for item in self.chosen:
                    if value.lower() in item.lower():
                        data.append(item)
    
                self.cbCombo['values'] = data
    
    
    def main():
        app = App()
        app.mainloop()
    
    
    if __name__ == '__main__':
        main()
    
    
    

    The keys are:

    
    self.bind('<KeyRelease>', self.check_input)
    
    
    
    self.chosen
    
    
    
        def check_input(self, event):
            value = event.widget.get()
    
            if value == '':
                self.cbCombo['values'] = self.chosen
            else:
                data = []
                for item in self.chosen:
                    if value.lower() in item.lower():
                        data.append(item)
    
                self.cbCombo['values'] = data