Can't make it work wx.Button.SetBackgroundColour on wx.EVT_ENTER_WINDOW

Hi again! :slight_smile:

Title says it all.
When I hover the button, I’ve got a very light grey/blue color. Only when I pressed and won’t let it go, it becames red. OnLeaveHover works fine. I’m on Windows 10.

The result:
Untitled

The code:

import wx

class MyClass(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.btn = wx.Button(self, -1)
        self.btn.Bind(wx.EVT_ENTER_WINDOW, lambda event: self.OnHover(event, self.btn))
        self.btn.Bind(wx.EVT_LEAVE_WINDOW, lambda event: self.OnLeaveHover(event, self.btn))

    def OnHover(self, event, button):
        button.SetBackgroundColour(wx.RED)

    def OnLeaveHover(self, event, button):
        button.SetBackgroundColour(wx.BLUE)

app = wx.App()
frame = MyClass(None)
frame.Show()
app.MainLoop()

Thanks!

Your code works on my Linux* PC - the button becomes red on entering and blue on leaving.

*Python 3.8.5 + wxPython 4.1.1 gtk3 (phoenix) wxWidgets 3.1.5 on Linux Mint 20.1

1 Like

Thanks for your input.
Maybe it’s plataform dependent. :frowning_face:

You may add a call to button.Refresh() after setting the colour.

P.S.: To avoid unnecessary refreshes, I’m using code like this:

    def _set_background_colour(self, bgcolor=wx.WHITE):
        if bgcolor!=self.GetBackgroundColour():
            self.SetBackgroundColour(bgcolor)
            self.Refresh()
1 Like

I tried this aproach and the behaviour remains the same. :frowning:

Well, Windows 10 replaces the background colour with the light blue color when the button has the focus.
I have not tried, but bitmaps could be an option:
https://wxpython.org/Phoenix/docs/html/wx.AnyButton.html#wx.AnyButton.SetBitmapFocus

P.S.: Generic Buttons would probably be the best options. See the demo GenericButtons.py.

1 Like

wx tries to keep the OS standard and I think it does it pretty well; by the way, wx.Event is a very cute object (as most of wx objects) and event.GetEventObject() will give the button which would not only reduce the number of instance attributes…

or use the Gamer version (will look even better if some aqua etc…)

import wx

class MyClass(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        btn = wx.Button(self, -1, label='Gamer button')
        btn.Bind(wx.EVT_ENTER_WINDOW, lambda enter: self.OnHover(True))
        btn.Bind(wx.EVT_LEAVE_WINDOW, lambda enter: self.OnHover(False))
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(btn, 1, wx.ALL|wx.EXPAND, 8)
        self.SetSizer(hbox)

    def OnHover(self, enter):
        self.SetBackgroundColour(wx.RED if enter else wx.BLUE)
        self.Refresh()

app = wx.App()
frame = MyClass(None)
frame.Show()
app.MainLoop()type or paste code here
1 Like

or out of the box…

gamer_button_cls.py (976 Bytes)

1 Like

Thanks for the file. That border is very nice indeed!
I’ll play with it!

Thank you very much!

Of course, for the gamer the button has to focus and selection is by space bar…

gamer_button_cls_evt_skip.py (1.4 KB)

But for the more cautious user an accidental space bar select can be avoided…

gamer_button_cls_evt_skip_nsb.py (995 Bytes)

And whilst we are playing what about this holy segregation of control & event handling: a few more lines, but… :innocent:

gamer_button_cls_evthdlr.py (1.8 KB)

…and watching the kids pass away gives an idea of the predictability (awaitables) of the destructor

gamer_button_cls_evthdlr_fun.py (2.1 KB)

and all animations (and not only them) off into threads… :joy:

gamer_button_cls_evthdlr_flash.py (2.6 KB)