Changing Button Appearance On Click

10,279

It was so many times on Stackoverflow so I don't know if I should write it again.

Button has command= to assign function but it can assign function without arguments. If you need with arguments you have to use lambda. I assign function with reference to button so function can use correct button and change it.

lambda in for-loop needs arg=btn and select_button(arg) because direct select_button(btn) will use last button in all functions.


As for changing previous button to original color you can use variable to remember previusly clicked button and then you can easily change it color.

Problem can be to find oryginal color of button so I copy it from new clicked button.

import tkinter as tk

# --- functions ---

def select_button(widget):
    global previously_clicked

    if previously_clicked:
        previously_clicked['bg'] = widget['bg']
        previously_clicked['activebackground'] = widget['activebackground']
        previously_clicked['relief'] = widget['relief']

    widget['bg'] = 'green'
    widget['activebackground'] = 'green'
    widget['relief'] = 'sunken'

    previously_clicked = widget

# --- main ---

names = ['Button A', 'Button B', 'Button C']

root = tk.Tk()

previously_clicked = None

for i, name in enumerate(names, 2):
    btn = tk.Button(root, text=name)

    btn.config(command=lambda arg=btn:select_button(arg))
    #btn['command'] = lambda arg=btn:select_button(arg)

    btn.grid(row=i, column=0, sticky='w')

root.mainloop()

EDIT: you can also use Radiobutton with some options to do the same - and without function:

see: http://effbot.org/tkinterbook/radiobutton.htm

import tkinter as tk

# --- functions ---

def select_button():
    print('value:', v.get())  # selected value

# --- main ---

names = ['Button A', 'Button B', 'Button C']

root = tk.Tk()

v = tk.IntVar()  # variable for selected value

for i, name in enumerate(names, 2):
    btn = tk.Radiobutton(root, text=name, variable=v, value=i)  # assign variable and value

    btn['indicatoron'] = 0  # display button instead of radiobutton
    btn['selectcolor'] = 'green' # color after selection

    btn['command'] = select_button  # function without variables

    btn.grid(row=i, column=0, sticky='w', ipadx=5, ipady=5)

root.mainloop()
Share:
10,279

Related videos on Youtube

Astrodude11
Author by

Astrodude11

Updated on September 15, 2022

Comments

  • Astrodude11
    Astrodude11 over 1 year

    In my GUI application I create a button for every item in a given list. When a button is pressed the background of said button turns green and it appears as "sunken". The other buttons appear raised and with the default color. My issue is that only the last button created changes color and appearance. I believe this is because it contains the callback function.

    I desire that after the initial button press, when a user presses a different button that the new button turns green and appears sunken and the previous button becomes raised and the default color. My guess is that I need to create a list of all created buttons and apply logic to it in the callback function for my desired behavior. But how so?

    # ---callback functions---
    def select_button():
        btn.config(bg='green', activebackground='green', relief=SUNKEN)
    
    # ---main---
    # List of buttons to be created
    list = ['A', 'B', 'C']
    buttons = []
    
    # Create buttons
    for i, name in enumerate(list, 2):
        btn = Button(root, text=name, command=select_button)
        btn.grid(row=i, column=0, sticky=W)
        buttons.append(btn)
    
  • Astrodude11
    Astrodude11 over 7 years
    Yes, this is a common question but my case is different. How do I change the appearance of the initial button after a new button is pressed? This initial button should be configured to its original state.
  • furas
    furas over 7 years
    now I see what you need. - you can use variable to remember previously clicked button and then you can change it to oryginal value.
  • furas
    furas over 7 years
    I add example with Radiobutton
  • Astrodude11
    Astrodude11 over 7 years
    I thought about using radio buttons instead of buttons but did not know about btn['indicatoron']. I like that they look like buttons but act as radio buttons. Thanks!