Tkinter: Button hover highlight doesn't work until I manually <Enter> then <Leave> then <Enter>

101 Views Asked by At

When I hover over my tkinter buttons, they are supposed to highlight by changing the background. It works, but only after I manually Enter then Leave then Enter each button.

My actual program has 100+ buttons and I don't want the user to have to hover over all of them before the hover highlighting starts to work!

Here's my simplified code: How can I make the hovering work the FIRST time?

from tkinter import *

DEFAULT_BG = "#AAAAAA"
DEFAULT_FG = "#000000"
DEFAULT_BG_HIGHLIGHT = "#DDDDDD"
all_cards = ["Button0", "Button1", "Button2", "Button3"]
all_buttons = []

main_window = Tk()
main_window.geometry("+20+20")

button_window = Toplevel()
button_window.geometry("+200+20")


def mouse_highlight_enter(e):
    print("mhe" + str(e.widget))
    e.widget['background'] = DEFAULT_BG_HIGHLIGHT


def mouse_highlight_leave(e):
    print("mhl" + str(e.widget))
    e.widget['background'] = DEFAULT_BG


for i in range(0, 4):
    all_buttons.append(Button(button_window,
                              text=all_cards[i],
                              font=("Comic Sans", 8, "bold"),
                              fg=DEFAULT_FG,
                              bg=DEFAULT_BG,
                              activeforeground=DEFAULT_FG,
                              activebackground=DEFAULT_BG,
                              relief=FLAT,
                              state=ACTIVE))
    all_buttons[i].pack()

    all_buttons[i].bind("<Enter>", mouse_highlight_enter)
    all_buttons[i].bind("<Leave>", mouse_highlight_leave)
    # all_buttons[i].event_generate("<Enter>")
    # all_buttons[i].event_generate("<Leave>")
    # all_buttons[i].update()

Button(main_window,
       text="Irrelevant Button",
       font=("Comic Sans", 8, "bold"),
       fg=DEFAULT_FG,
       bg=DEFAULT_BG,
       activeforeground=DEFAULT_FG,
       activebackground=DEFAULT_BG,
       relief=RAISED,
       state=ACTIVE).pack()

main_window.mainloop()

Thanks in advance for your help. :)

1

There are 1 best solutions below

5
On

The problem lies here. Remove these two lines:

activeforeground=DEFAULT_FG,
activebackground=DEFAULT_BG,

In both the windows, change the button state to NORMAL. And in the functions, change the bg to DEFAULT_BG instead of DEFAULT_BG_HIGHLIGHT

state=NORMAL
e.widget['background'] = DEFAULT_BG #in functions

The reason is, button hovering is triggered by a function. But activeforeground and active background override the background insisted by the function.

And by default, is the button state is active and bg & fg colors triggered by the function are also similar to that of active, There won't be any change in color while hovering.

So,, the complete code after correction is:

from tkinter import *

DEFAULT_BG = "#AAAAAA"
DEFAULT_FG = "#000000"
DEFAULT_BG_HIGHLIGHT = "#DDDDDD"
all_cards = ["Button0", "Button1", "Button2", "Button3"]
all_buttons = []

main_window = Tk()
main_window.geometry("+20+20")

button_window = Toplevel()
button_window.geometry("+200+20")


def mouse_highlight_enter(e):
    print("mhe" + str(e.widget))
    e.widget['background'] = DEFAULT_BG


def mouse_highlight_leave(e):
    print("mhl" + str(e.widget))
    e.widget['background'] = DEFAULT_BG


for i in range(0, 4):
    all_buttons.append(Button(button_window,
                              text=all_cards[i],
                              font=("Comic Sans", 8, "bold"),
                              fg=DEFAULT_FG,
                              bg=DEFAULT_BG,
                             
                             
                              relief=FLAT,
                              state=NORMAL))
    all_buttons[i].pack()

   
    all_buttons[i].bind("<Enter>", mouse_highlight_enter)
    all_buttons[i].bind("<Leave>", mouse_highlight_leave)
    # all_buttons[i].event_generate("<Enter>")
    # all_buttons[i].event_generate("<Leave>")
    # all_buttons[i].update()



Button(main_window,
       text="Irrelevant Button",
       font=("Comic Sans", 8, "bold"),
       fg=DEFAULT_FG,
       bg=DEFAULT_BG,
       
     
       relief=RAISED,
       state=NORMAL).pack()

main_window.mainloop()

Checked for the performance. It works now. Your thanks has been taken in advance.