Python EVT_SET_FOCUS
When I run this code and focus on choice it is raise a error. I close this message but it is come back again. I want to see only one time this message. How can i do this? What is error in my code ?
#! -*- coding:utf-8 -*-
import wx
class MyPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.my_choice = wx.Choice(self, wx.NewId())
self.my_button = wx.Button(self, wx.NewId(), label = "Procces")
self.my_button.SetFocus()
sizer.AddMany([(self.my_choice, 0, wx.ALL, 5),
(self.my_button, 0, wx.ALL, 5)])
self.SetSizer(sizer)
self.my_choice.Bind(wx.EVT_SET_FOCUS, self.my_choice_on_focus)
self.my_button.Bind(wx.EVT_BUTTON, self.my_button_on_clicked)
def my_choice_on_focus(self, evt):
try:
self.my_choice.Clear()
print "Input some items in my_choice"
raise RuntimeError
except RuntimeError:
dlg = wx.MessageDialog(self, "test EVT_SET_FOCUS", "Error", wx.ICON_ERROR|wx.OK )
dlg.ShowModal()
dlg.Destroy()
raise
evt.Skip()
def my_button_on_clicked(self, evt):
print "Procces my choice value"
evt.Skip()
class MyApp(wx.App):
def 开发者_如何转开发OnInit(self):
frame = wx.Frame(None, title = "Test")
panel = MyPanel(frame)
frame.Show()
self.SetTopWindow(frame)
return True
if __name__ == '__main__':
app = MyApp(redirect = False)
app.MainLoop()
The error dialog gets the focus when it is shown. When you close the error dialog, the focus returns to the choice control, firing the event handler again, which pops up the error dialog again, et cetera.
To avoid the event handler from being invoked multiple times, one solution would be to unbind the wx.EVT_SET_FOCUS. Another would be not to bind to wx.EVT_SET_FOCUS at all and do the action that you want to do in my_choice_on_focus somewhere else and/or at another moment in time.
I solved my problem with following code. Thanks to everyone for help.
#! -*- coding:utf-8 -*-
import wx
import wx.lib.evtmgr as em
class MyPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.my_choice = wx.Choice(self, wx.NewId())
self.my_choice.Append("Make your selection")
self.my_choice.Select(0)
self.my_button = wx.Button(self, wx.NewId(), label = "Procces")
self.my_button.SetFocus()
sizer.AddMany([(self.my_choice, 0, wx.ALL, 5),
(self.my_button, 0, wx.ALL, 5)])
self.SetSizer(sizer)
em.eventManager.Register(self.my_choice_set_focus, wx.EVT_SET_FOCUS, self.my_choice)
em.eventManager.Register(self.my_choice_on_select, wx.EVT_CHOICE, self.my_choice)
em.eventManager.Register(self.my_button_on_clicked, wx.EVT_BUTTON, self.my_button)
def my_choice_on_select(self, evt):
if evt.GetSelection() <= 0:
print "Procces false selection"
em.eventManager.Register(self.my_choice_set_focus,
wx.EVT_SET_FOCUS,
self.my_choice)
self.SetFocusIgnoringChildren()
else:
print "Procces true selection"
evt.Skip()
def my_choice_set_focus(self, evt):
try:
self.my_choice.Clear()
self.my_choice.Append("Make your selection")
raise RuntimeError
except RuntimeError:
em.eventManager.DeregisterListener(self.my_choice_set_focus)
dlg = wx.MessageDialog(None, "test EVT_SET_FOCUS", "Error",
wx.ICON_ERROR|wx.OK )
dlg.ShowModal()
dlg.Destroy()
self.my_choice.Clear()
self.my_choice.Append("Try again...")
self.my_choice.Select(0)
evt.Skip()
evt.Skip()
def my_button_on_clicked(self, evt):
print "Procces my choice value"
evt.Skip()
class MyApp(wx.App):
def OnInit(self):
frame = wx.Frame(None, title = "Test")
panel = MyPanel(frame)
frame.Show()
self.SetTopWindow(frame)
return True
if __name__ == '__main__':
app = MyApp(redirect = False)
app.MainLoop()
精彩评论