Reputation: 433
I have written the following code to create 4 buttons and after clicking at a button the background color of this button is changing and when I click at another one the color of this one is now changing and the color of the old one is changing back to default color. It works quite well but the coding is not efficient. I'm thinking of a loop which iterates through all my buttons to set all buttons which are not active to the default color. How can I accomplish this?
from tkinter import *
def update_Button(number):
if number == 1:
Button_1["background"] = Button_1["activebackground"] = "lightblue"
Button_2.configure(background="SystemButtonFace")
Button_3.configure(background="SystemButtonFace")
Button_4.configure(background="SystemButtonFace")
elif number == 2:
Button_2["background"] = Button_2["activebackground"] = "lightblue"
Button_1.configure(background="SystemButtonFace")
Button_3.configure(background="SystemButtonFace")
elif number == 3:
Button_3["background"] = Button_3["activebackground"] = "lightblue"
Button_2.configure(background="SystemButtonFace")
Button_1.configure(background="SystemButtonFace")
Button_4.configure(background="SystemButtonFace")
elif number == 4:
Button_4["background"] = Button_4["activebackground"] = "lightblue"
Button_2.configure(background="SystemButtonFace")
Button_3.configure(background="SystemButtonFace")
Button_1.configure(background="SystemButtonFace")
pass
root = Tk()
Button_font = ("Calibri", 20, "bold")
Button_Size = [70, 70] # width, height
pady = 5
padx = 5
Button_1 = Button(root, text="1", font=Button_font, command=lambda: update_Button(1))
Button_1.grid(sticky="wens", pady=pady, padx=padx)
Button_2 = Button(root, text="2", font=Button_font, command=lambda: update_Button(2))
Button_2.grid(sticky="wens", pady=pady, padx=padx)
Button_3 = Button(root, text="3", font=Button_font, command=lambda: update_Button(3))
Button_3.grid(sticky="wens", pady=pady, padx=padx)
Button_4 = Button(root, text="4", font=Button_font, command=lambda: update_Button(4))
Button_4.grid(sticky="wens", pady=pady, padx=padx)
root.mainloop()
like suggest from @Mitiku the solution using a list is:
def update_Button(number):
number = number-1
buttons = [Button_1, Button_2, Button_3, Button_4]
buttons[number]["background"] = buttons[number]["activebackground"] = "lightblue"
for button in buttons:
if button == buttons[number]:
pass
else:
button.configure(background="SystemButtonFace")
pass
Upvotes: 1
Views: 2541
Reputation: 4740
The below achieves what you need:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.number = 4 #change me to get more buttons
self.buttons = []
for i in range(self.number):
self.buttons.append(Button(self.root, text="Change!", bg="white", command=lambda c=i: self.command(c)))
self.buttons[i].pack()
def command(self, var):
for i in range(self.number):
self.buttons[i].configure({"bg": "white", "activebackground": "white"})
self.buttons[var].configure({"bg": "lightblue", "activebackground": "lightblue"})
root = Tk()
App(root)
root.mainloop()
The main interesting mechanic we use here is lambda
.
We declare command=lambda c=i: self.command(c)
which let's us call the command
callback with the value of i
at the time of declaration. This means when we call the command we pass through the integer value of the Button
widget's position in the list
.
On a side note, this can be accomplished much easier with Radiobutton
s. See below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.v = IntVar()
self.number = 4 #change me to get more buttons
self.buttons = []
for i in range(self.number):
self.buttons.append(Radiobutton(self.root, text="Change!", bg="white", activebackground="lightblue", selectcolor="lightblue", variable=self.v, indicatoron=0, value=i))
self.buttons[i].pack()
root = Tk()
App(root)
root.mainloop()
Upvotes: 1
Reputation: 5412
you can use list.
def update_Button(number):
buttons = [Button_1,Button_2,Button_3,Button_4]
for button in buttons:
button.configure(background="SystemButtonFace")
buttons[number-1]["activebackground"] = "lightblue"
Upvotes: 0