Reputation: 58
I am trying to understand how EVT_KILL_FOCUS and SetFocus on a combobox works .Here is the following code:
import wx
class MainWindow(wx.Frame):
count = 1
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(150,150), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
panel = wx.Panel(self, -1)
self.Calc_Display = wx.ComboBox(panel, -1, style=wx.CB_DROPDOWN|wx.TE_PROCESS_ENTER)
self.Calc_Display.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
btn = wx.Button(panel, label="Test")
MainFrameSizer = wx.BoxSizer(wx.VERTICAL)
MainFrameSizer.Add(self.Calc_Display, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 5)
MainFrameSizer.Add(btn, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 5)
panel.SetSizer(MainFrameSizer)
panel.Fit()
self.Show()
def OnKillFocus(self, event):
print ('EVT_KILL_FOCUS was called %i times' %MainWindow.count)
MainWindow.count += 1
# self.Calc_Display.SetFocus()
event.Skip()
app = wx.App(False)
frame = MainWindow(None, "Test")
app.MainLoop()
If run this, you will get a print every time the combobox loses focus, which is expected. If you uncomment line 28, that's when it gets weird. The EVT_KILL_FOCUS gets called over and over. That is the behavior I am trying to understand. In the program I am writing, I want to force the combobox to maintain focus in case a condition is not satisfied. Are there any ways around this behavior?
I found this link on the issue, but I did not quite understand it: http://wiki.wxpython.org/Surviving%20with%20wxEVT%20KILL%20FOCUS%20under%20Microsoft%20Windows
Thanks for any help
Upvotes: 2
Views: 1121
Reputation: 2295
After reading the link posted in your question, and playing around with your code, I came to the conclusion that calling SetFocus()
on the combobox
is apparently triggering the EVT_KILL_FOCUS
in Windows. I had noticed that on running the program, it prints the statement once, although It shouldn't since the combobox
is not losing focus.
I tried two things:
First was to move the combo box code after the button code. In this case when the program is run the Focus is on the button, and sure enough the statement is not printed!
Here's the edit:
btn = wx.Button(panel, label="Test")
self.Calc_Display = wx.ComboBox(panel, -1, style=wx.CB_DROPDOWN|wx.TE_PROCESS_ENTER)
self.Calc_Display.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
Second was to try binding the btn
to a handler which sets the focus on the combobox
btn.Bind(wx.EVT_BUTTON, self.On_Button)
def On_Button(self, event):
self.Calc_Display.SetFocus()
In this case the statement was being printed twice every time the button was being clicked. I guess this is once for when the focus is lost and once for setting back the focus. Note that the SetFocus()
is still commented out in the OnKillFocus
in this case.
Back to your code: If the SetFocus
is "uncomment-ed" the statement is printed many times because it keeps setting the focus which in turn triggers the event and it goes on in a loop. This may be a wrong explanation, but nevertheless it is the only thing I could think of.
Upvotes: 3