Home > database >  Tkinter Update list of buttons depending on a click of another list of buttons
Tkinter Update list of buttons depending on a click of another list of buttons

Time:05-26

I am new to tkinter. I have a list of buttons A and when I select one of the buttons I can also update a label (see code). Now I would like to have a second list of buttons B where the number of buttons (and functionality) depends on the click on a button from the list of buttons A (I tried to show this in the picture).

What am I doing wrong here? Can you help me please!

import tkinter as tk
  
root = tk.Tk()
root.title("Analyser")
root.geometry("750x250")

group_number = tk.StringVar()
l0 = tk.Label(root, textvariable=group_number, width=20)
l0.grid(row=1,column=1)

def func(n):
    group_number.set("Selected Button: Button "   str(n 1))
    

Buttons_A = ["Button 1","Button 2"]

l2 = tk.Label(root, text = "BUTTONS A",font=('Helvetica', 12, "bold"), fg='white', bg='#107baf', width=20)
l2.grid(row=0, column=0,padx=4,pady=8)


for i in range(len(Buttons_A)):
    btn=tk.Button(root, text=Buttons_A[i], font=('Helvetica', 10), bg='#d8e7ea', width=20, activebackground='#42bed8')
    btn.config(command=lambda n=i:func(n))
    btn.grid(row=i 1,column=0, padx=4,pady=4)
    

Buttons_B_1 = ["Button 1","Button 2","Button 3"]
Buttons_B_2 = ["Button 1"]


l2 = tk.Label(root, text = "BUTTONS B",font=('Helvetica', 12, "bold"), fg='white', bg='#107baf', width=20)
l2.grid(row=0, column=2,padx=4,pady=8)


for i in range(len(Buttons_B_1)):
    btn=tk.Button(root, text=Buttons_B_1[i], font=('Helvetica', 10), bg='#d8e7ea', width=20, activebackground='#42bed8')
    btn.config(command=lambda n=i:func(n))
    btn.grid(row=i 1,column=2, padx=4,pady=4)
    
       
root.mainloop()

When Button 1 is selected from Button List A When Button 2 is selected from Button List A

CodePudding user response:

You should keep buttons B on list so you could easily destroy them.

When you click button A then it runs func and inside this function you should destroy buttons from list, clear this list, create new buttons and add them to this list.

Code will be simpler if you will keep buttons B1 and B2 as sublists on one list.


Minimal working code.

I removed fonts and colors to show only important elements.

import tkinter as tk

# --- functions ---

def func(n):
    group_number.set(f"Selected Button: Button {n 1}")
    create_buttons_B(n)

def create_buttons_B(selected_button_1):

    # remove previous buttons 
    
    for button in existing_buttons_B:
        button.destroy()

    # clear list

    existing_buttons_B.clear()
    
    # create new buttons and add to list
        
    buttons = Buttons_B[selected_button_1]
    
    for number, text in enumerate(buttons):
        btn = tk.Button(root, text=text)
        btn.grid(row=number 1, column=2)

        existing_buttons_B.append(btn)
        
# --- main ---

Buttons_A = ["Button 1", "Button 2"]

Buttons_B = [
    ["Button B1 1", "Button B1 2", "Button B1 3"],
    ["Button B2 1"],
]    

existing_buttons_B = []  # list for created buttons B

root = tk.Tk()

group_number = tk.StringVar(root)
l0 = tk.Label(root, textvariable=group_number, width=20)
l0.grid(row=1, column=1)

l2 = tk.Label(root, text="BUTTONS A")
l2.grid(row=0, column=0)

for number, text in enumerate(Buttons_A):
    btn = tk.Button(root, text=text, command=lambda n=number:func(n))
    btn.grid(row=number 1, column=0)

l2 = tk.Label(root, text="BUTTONS B")
l2.grid(row=0, column=2)
   
#create_buttons_B(0)  # create buttons at start

root.mainloop()

Eventually you could use Frame to group buttons and then you have to destroy only this Frame and it will destroy also buttons.

But you can also first create Frames with buttons and put buttons in frames and later use grid_forget() to remove one frame and grid() to show another frame.

CodePudding user response:

It is easier to associate the required lists using dictionary for Buttons_A instead of separated lists:

Buttons_A = {
    "Button 1": ["Button 1", "Button 2", "Button 3"],
    "Button 2": ["Button 1"]
}

Also better use frames to group buttons, so that you can just destroy buttons in "BUTTONS B" and then create new ones whenever a button in "BUTTONS A" is clicked.

import tkinter as tk

root = tk.Tk()
root.title("Analyser")
root.geometry("750x250")

group_number = tk.StringVar()
l0 = tk.Label(root, textvariable=group_number, width=20)
l0.grid(row=1, column=1, sticky='n')

def func(btn):
    group_number.set("Selected Button: " btn)
    # clear current buttons shown in frame_B
    for w in frame_B.winfo_children():
        w.destroy()
    # populate required buttons
    for item in Buttons_A[btn]:
        btn = tk.Button(frame_B, text=item, font=('Helvetica', 10), bg='#d8e7ea', width=20, activebackground='#42bed8')
        btn.pack(padx=4, pady=4)


Buttons_A = {
    "Button 1": ["Button 1", "Button 2", "Button 3"],
    "Button 2": ["Button 1"]
}

l2 = tk.Label(root, text="BUTTONS A", font=('Helvetica', 12, "bold"), fg='white', bg='#107baf', width=20)
l2.grid(row=0, column=0, padx=4, pady=8)

# frame for "Buttons A"
frame_A = tk.Frame(root)
frame_A.grid(row=1, column=0, sticky='n')

for item in Buttons_A:
    btn = tk.Button(frame_A, text=item, font=('Helvetica', 10), bg='#d8e7ea', width=20, activebackground='#42bed8')
    btn.config(command=lambda x=item:func(x))
    btn.pack(padx=4, pady=4)

l2 = tk.Label(root, text="BUTTONS B", font=('Helvetica', 12, "bold"), fg='white', bg='#107baf', width=20)
l2.grid(row=0, column=2, padx=4, pady=8)

# frame for "Buttons B"
frame_B = tk.Frame(root)
frame_B.grid(row=1, column=2, sticky='n')

root.mainloop()
  • Related