Search code examples
pythontkintereventscombobox

Bind event to multiple widgits in list


I try to make multiple comboboxes performe the same command when being used - they should simutanously change values when one is used. I appended all of them to lists and wrote this code, which is not working.

import tkinter as tk
from tkinter import ttk
from tkinter import *
root = tk.Tk()

comboboxes=[]
entries=[]
values=['a', 'b', 'c']
c=ttk.Combobox(root,values=values)
c2=ttk.Combobox(root,values=values)
comboboxes.append(c)
comboboxes.append(c2)
e1 = Entry(root, bd=3)
e2 = Entry(root, bd=3)
entries.append(e1)
entries.append(e2)
for i in range(len(comboboxes)):
    comboboxes[i].pack()
    entries[i].pack()


for i in range(len(comboboxes)):    
    for i in range(len(comboboxes)):
      def combo(event):
        for i in range(len(comboboxes)):
            X=  str(comboboxes[i].get()) 
            if X==("a"):
                A=3
            elif X==("b"):
                A=2
            elif X==("c"):
                A=1

            entries[i].delete(0, 'end')
            entries[i].insert(END, A )
    comboboxes[i].bind('<<ComboboxSelected>>', combo )
root.mainloop()

I'd be very grateful for help. Thank you in advance.


Solution

  • Wow.

    It is code like this which should remind us all that in a production environment we often must work with legacy code which we do not have the luxury of rewriting. I don't say that to be hurtful as you're obviously new to both Python and TKinter, I just think it's worth noting as it's something which hobby programmers, or professionals who've never had to work in a corporate environment, don't often think about.

    In the spirit of having said that, this is not how I would have approached this problem, but I've tried to "fix" the code without completely rewriting it. In the end it was probably as much work to modify as it would have been to rewrite.

    I've commented out your code that I "removed" to make it easier for you to compare your original code to what I've changed. I've marked the lines that I've added, modified, or moved.

    I also changed the values list to a dictionary to get rid of all the if statements.

    import tkinter as tk
    from tkinter import ttk
    from tkinter import *
    
    ###############
    # I've moved this entire block of code to the top so that combo() is
    #   recognized before anything else runs.
    ###############
    #for i in range(len(comboboxes)):    
    #    for i in range(len(comboboxes)):
    def combo(event):
        for i in range(len(comboboxes)):
            if comboboxes[i] == event.widget:   ### NEW LINE ###
                for j in range(len(entries)):   ### MODIFIED ###
                    entries[j].delete(0,'end')  ### MODIFIED ###
                    entries[j].insert(0, values[comboboxes[i].get()]) ### NEW LINE ###
            # X=  str(comboboxes[i].get()) 
                # if X==("a"):
                    # A=3
                # elif X==("b"):
                    # A=2
                # elif X==("c"):
                    # A=1
                # entries[i].insert(END, A )
    
    
    root = tk.Tk()
    
    comboboxes=[]
    entries=[]
    values = {'a':3, 'b':2, 'c':1} ### NEW LINE ###
    #values=['a', 'b', 'c']
    c=ttk.Combobox(root,values=list(values.keys()))     ### MODIFIED ###
    c2=ttk.Combobox(root,values=list(values.keys()))    ### MODIFIED ###
    comboboxes.append(c)
    comboboxes.append(c2)
    e1 = Entry(root, bd=3)
    e2 = Entry(root, bd=3)
    entries.append(e1)
    entries.append(e2)
    for i in range(len(comboboxes)):
        comboboxes[i].pack()
        comboboxes[i].bind('<<ComboboxSelected>>', combo) ### MOVED ###
        entries[i].pack()
    
    
    root.mainloop()
    

    As an additional note I want to point out that the only place you use c, c2, e1, and e2 are for the purposes of adding them to lists. You can do this without using variable names:

    comboboxes.append(ttk.Combobox(root,values=list(values.keys())))
    comboboxes.append(ttk.Combobox(root,values=list(values.keys())))
    entries.append(Entry(root, bd=3))
    entries.append(Entry(root, bd=3))