The only thing I can think of is to decouple the code that decides when
to set the bg color out of the controls and move it into some sort of
highlight manager class. When a control that is supposed to set its bg
color receives the focus then it asks the highlight manager if it can do
it. The highlight manager keeps track of which control currently has
the highlight and notifies it if a new control requests it so the
current one can reset its bg to the default. Since the buttons would
not request the highlight then the current highlighted control would not
lose it.
I implemented something close to this proposal and it works nicely, but
there was still one small problem. If I covered my application and then
exposed it, the shading would disappear. I solved the problem, but I am
not confident that my solution is optimal. First I catch the paint event
directed to the main panel:
def doMainPanelPaint(self, event):
wx.PaintDC(self) # online doc says must create PaintDC object
# even if not used
self.backgroundManager.resetFocus()
event.Skip()
Then the BackgroundManager restores the background:
I am worried about this solution because doMainPanelPaint gets called
frequently for events that have nothing to do with restoring the background
shading. Is there another event that relates more closely to the problem I
am solving? Is the overhead for my handler small? I suppose that
something like the wx.PaintDC call happens regardless, so if the call to
resetFocus is the extent of the overhead then perhaps it is negligible.
I just noticed that when I minimize and restore my application, the shading
is right but the application no longer responds to keyboard commands to
move the focus, so probably I still have something wrong.
The only thing I can think of is to decouple the code that decides when to set the bg color out of the controls and move it into some sort of highlight manager class. When a control that is supposed to set its bg color receives the focus then it asks the highlight manager if it can do it. The highlight manager keeps track of which control currently has the highlight and notifies it if a new control requests it so the current one can reset its bg to the default. Since the buttons would not request the highlight then the current highlighted control would not lose it.
I implemented something close to this proposal and it works nicely, but
there was still one small problem. If I covered my application and then
exposed it, the shading would disappear.
Since you are using SetBackgroundColour then that shouldn't happen. When the controls refresh themselves after they are damaged they should still use that background color. Are you doing anything that would get the setting of the bg color out of sync with where it should be?
I solved the problem, but I am
not confident that my solution is optimal. First I catch the paint event
directed to the main panel:
def doMainPanelPaint(self, event):
wx.PaintDC(self) # online doc says must create PaintDC object
# even if not used
self.backgroundManager.resetFocus()
event.Skip()
Since you are calling Skip then you shouldn't need to create the wx.PaintDC since the default handler will do it.
Then the BackgroundManager restores the background:
I am worried about this solution because doMainPanelPaint gets called
frequently for events that have nothing to do with restoring the background
shading. Is there another event that relates more closely to the problem I
am solving? Is the overhead for my handler small? I suppose that
something like the wx.PaintDC call happens regardless, so if the call to
resetFocus is the extent of the overhead then perhaps it is negligible.
I just noticed that when I minimize and restore my application, the shading
is right but the application no longer responds to keyboard commands to
move the focus, so probably I still have something wrong.
Perhaps not calling Skip from a focus handler? Also, when the window is restored the control that last had the focus will get another focus event as the focus is restored, so be sure that there isn't anything that could go wonky if the control that it thinks already has the focus gets it again.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Also, when the window is
restored the control that last had the focus will get another focus
event as the focus is restored, so be sure that there isn't anything
that could go wonky if the control that it thinks already has the focus
gets it again.
Not only do I get multiple set focus events, but I also get a kill focus
event on the window that should have the focus. Normally it is immediately
reversed by a set focus event, but my code was not handling that duple
correctly. Now I detect whether the kill/set duple is directed to the
window that already has the shading. If so, I don't make any changes to
the background shading. Works great now without a paint event handler.