Search code examples
pythonpython-3.xtkinterbind

How can I bind a combobox to a Radiobutton


I have some Radiobuttons. Depending of what Radio button was selected I want to have different Combobox values. I don't know how I can solve the problem. In a further step I want to create further comboboxes which are dependend on the value of the first.

The following code creates the list of user, but it does not show up in the combobox.

For me it is difficult to understand where the right position of functions is, and if I need a lambda function nor a binding.

import tkinter as tk
from tkinter import ttk
import pandas as pd
import os

global version
global df_MA
df_MA = []


class Window(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)

        self.geometry('300x100')
        self.title('Toplevel Window')
        self.btn = ttk.Button(self, text='Close',command=self.destroy).pack(expand=True)

class App(tk.Tk):

    def __init__(self,*args, **kwargs):
        super().__init__()

        # def load_input_values(self):
        def set_department(department):
            if department == "produktion":
                working_df_complete = path_input_produktion
            if department == "service":
                working_df_complete = path_input_service

            working_df_complete = pd.read_excel(working_df_complete)
            working_df_complete = pd.DataFrame(working_df_complete)
            '''set worker df'''
            df_MA = working_df_complete.loc[:,'MA']
            df_MA = list(df_MA.values.tolist())

        def select_working_step():

            return

        '''Define Variable Bereich aofter clicking of radio button '''
        '''SEEMS TO ME UNECCESSARY COMPLICATED, but I dont't know how to do it properly. I am no progammer'''

        border = 10
        spacey = 10

        '''paths for input file'''
        path_input_produktion = os.path.abspath('input_data\werte_comboboxen_produktion.xlsx')
        path_input_service = os.path.abspath('input_data\werte_comboboxen_service.xlsx')

        self.geometry('500x600')


        '''Variablen for department'''
        department = tk.StringVar()
        department.set(" ")

        '''place Frame department'''
        self.rb_frame_abteilung = tk.Frame(self)
        '''Radiobuttons for department'''
        rb_abteilung_produktion = tk.Radiobutton(self.rb_frame_abteilung, text="Produktion", variable= department,
                                                 value="produktion", command= lambda: set_department(department.get()))

        rb_abteilung_service = tk.Radiobutton(self.rb_frame_abteilung, text="Service", variable= department,
                                              value="service", command= lambda: set_department(department.get()) )

        rb_abteilung_produktion.pack(side="left", fill=None, expand=False, padx=10)
        rb_abteilung_service.pack(side="left", fill=None, expand=False, padx =10)
        self.rb_frame_abteilung.grid(row=5, column=1, sticky="nw", columnspan=99)


        self.label_user = ttk.Label(self, text='user').grid(row=15,
                                                                 column=15, pady=spacey,padx=border, sticky='w')
        self.combobox_user = ttk.Combobox(self, width = 10, value= df_MA)
        self.combobox_user.bind("<<ComboboxSelected>>", select_working_step)
        self.combobox_user.grid(row=15, column=20, pady=spacey, sticky='w')

if __name__ == "__main__":
    app = App()
    app.mainloop()
´´´

Solution

  • I rewrote everything using indexes and removing global variables...

    #!/usr/bin/python3
    import tkinter as tk
    from tkinter import ttk
    from tkinter import messagebox
    
    
    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 = ('Produktion','Service')
            self.df_MA_1 = ['Peter','Hans','Alfred']
            self.df_MA_2 = ['Otto','Friedrich','Tanja']
    
            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
            else:
                self.cbCombo["values"] = self.df_MA_2
                
            
        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()            
        
    

    enter image description here