How do I handle control events and kill focus event in the same Frame?

(Cross-posted from StackOverflow as it seems more likely to get an answer here)

I’m writing a class to generate a frame on left click of a taskbar icon. The desired behaviour is for this frame to disappear on loss of focus, so I have bound a wx.EVT_KILL_FOCUS event to the panel in my LeftClickFrame() object.

This works fine if I only have a wx.StaticText widget in the frame, but if I add a wx.HyperlinkCtrl the wx.EVT_KILL_FOCUS event no longer fires. I get the same blocking behaviour with wx.RadioButton widgets, but not with wx.StaticBitmap.

I believe this is something to do with the fact that wx.HyperlinkCtrl and wx.RadioButton widgets are both controls and emit command events, but I’m not clear on what I have to do to rearrange my class so the wx.EVT_KILL_FOCUS event is still processed when one or both of these controls are present.

I have attached the class I’m having trouble with - I hope this doesn’t post twice as I tried to post once with source code in the message.

Thanks.

leftclickframe.py (1.47 KB)

Jamie Bull wrote:

(Cross-posted from StackOverflow as it seems more likely to get an
answer here)

I'm writing a class to generate a frame on left click of a taskbar icon.
The desired behaviour is for this frame to disappear on loss of focus,
so I have bound a `wx.EVT_KILL_FOCUS` event to the panel in my
`LeftClickFrame()` object.

This works fine if I only have a `wx.StaticText` widget in the frame,
but if I add a `wx.HyperlinkCtrl` the `wx.EVT_KILL_FOCUS` event no
longer fires. I get the same blocking behaviour with `wx.RadioButton`
widgets, but not with `wx.StaticBitmap`.

I believe this is something to do with the fact that `wx.HyperlinkCtrl`
and `wx.RadioButton` widgets are both controls and emit command events,
but I'm not clear on what I have to do to rearrange my class so the
`wx.EVT_KILL_FOCUS` event is still processed when one or both of these
controls are present.

I have attached the class I'm having trouble with - I hope this doesn't
post twice as I tried to post once with source code in the message.

This is a combination of things. EVT_KILL_FOCUS is only sent to the widgets that have the keyboard focus, and if a panel has a child that can accept the focus then it will always pass the focus to the child and will never take the focus itself. So when you have just a StaticText on the panel then the panel will take the focus and will emit EVT_KILL_FOCUS when it loses it. But when you have a wx.HyperlinkCtrl or anything else then that widget gets the focus and so your panel's focus handler will never be called.

You will probably be able to do what you want by catching the Frame's EVT_ACTIVATE event. That should be sent both when the frame is activated and also when it is deactivated (when some other window is activated or gets the focus.)

···

--
Robin Dunn
Software Craftsman