0

My code is getting messy because of many operations for changing widgets state. For example I have around 8 buttons which I want to have fg='red', text='press to config" when value assigned to their connected variables is None (before the user make an input). Also for some of them I want to make them state='disabled' when certain conditions are met to prevent user from making any input. Is there a simple way to group them somehow and then use a single command? Something like:

for btn in btns_list:
    if btn connected variable is not None:
        btn.config(text='Press to reconfig', fg='green')

It looks like it could be somehow managed by dictionary, am I right? Any suggestions are appreciated, because for now around 1/5 of my code is having "fun" with changing the widgets config and when project is getting bigger it's not that easy to manage.

Dawid Rutkowski
  • 410
  • 3
  • 8

1 Answers1

2

You alredy use simple way,You can remember id of each button by my_btn = Button(master, ...), where my_btn will be id of the button. Then collect them in the list and use for loop each time you want to call all buttons you added by their id. See:

import tkinter as tk

button_list = []

master = tk.Tk()

def change_color():
    for button in button_list:
        button.config(bg='red')

my_btn = tk.Button(master, text="Button 1")
my_btn.pack()
button_list.append(my_btn)
my_btn = tk.Button(master, text="Button 2")
my_btn.pack()
button_list.append(my_btn)
my_btn = tk.Button(master, text="Button 3")
my_btn.pack()
button_list.append(my_btn)
my_btn = tk.Button(master, text="CHANGE COLOR", command=change_color)
my_btn.pack()


master.mainloop()

You can use dictionary instead of list to choose button you need, it will be better practice.

Of course you can refer to all buttons like in the code above, but I do not think you will ever need it.

BTW you do not need to use is not None, because if btn connected variable already return you boolean so your loop should look like:

for btn in btns_list:
    if btn connected variable:
        btn.config(text='Press to reconfig', fg='green')

EDIT 1:

Example with dictionary instead of the list:

import tkinter as tk

# dictionary with buttons
d = {} 
master = tk.Tk()

def change_color():
    # for loop for dict keys
    for button in d.keys():
        # here we refer to each button(value of button key)
        # and change the color
        #
        # here you can add some if statements to edit particular group
        # of buttons
        d[button].config(bg='red')

my_btn = tk.Button(master, text="Button 1")
my_btn.pack()
d['group1_btn_name1'] = my_btn
my_btn = tk.Button(master, text="Button 2")
my_btn.pack()
d['group2_btn_name2'] = my_btn
my_btn = tk.Button(master, text="Button 3")
my_btn.pack()
d['group1_btn_name3'] = my_btn
my_btn = tk.Button(master, text="CHANGE COLOR", command=change_color)
my_btn.pack()


master.mainloop()

But remember - each key in the dictionary should be unique, therefore button names (keys) should all be different (btn_name1, btn_name2, btn_name3). You can group them by adding prefixes like some_group_btn1, some_group_btn2 ... other_group_btnnnn...

You can create buttons and groups with any names, but something (for ex. _) should divide group prefix and button name for defining particular group names in dictionary keys. For example you can add such if statement:

if 'group1' in button.split('_'):
    d[button].config(bg='red')

It will modify buttons which refer to only group1 group. But remember that division sign _ or - of you want should always be the same because of split operation.

  1. Check about dictionary keys here
  2. About split here
  • But I wonder what is the best approach for connecting variables to buttons (to make the loop work). Maybe I should make a dictionary instead of a list? How to implement this? – Dawid Rutkowski Apr 04 '20 at 14:27
  • @DawidRutkowski please see my edit 1, there is an example with dictionaries –  Apr 05 '20 at 09:32