Call Functions From Within A Wxpython Event Handler
Solution 1:
The following code shows how to create a little method that you can reuse to show custom dialogs and tells the user that they need to accept the agreement. You can change the conditionals to do whatever you want, of course. And you can change the "showMsg" method so that the icon changes too with just a little tweaking.
import wx
########################################################################classTestFrame(wx.Frame):
""""""#----------------------------------------------------------------------def__init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Test")
panel = wx.Panel(self)
self.radios = wx.RadioBox(panel, label="Choices",
choices = ["None", "Accept", "Reject"])
button = wx.Button(panel, label="Run")
button.Bind(wx.EVT_BUTTON, self.onBtn)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.radios, 0, wx.ALL, 5)
sizer.Add(button, 0, wx.ALL, 5)
panel.SetSizer(sizer)
#----------------------------------------------------------------------defonBtn(self, event):
""""""
btn = event.GetEventObject()
btn.SetLabel("Running")
radio_value = self.radios.GetStringSelection()
if radio_value == "None":
self.showMsg("Error", "Please Choose 'Accept' or 'Reject'!")
elif radio_value == "Accept":
self.showMsg("Message", "Thank you for accepting!")
else:
self.showMsg("Message", "We're sorry, but you cannot continue the install")
#----------------------------------------------------------------------defshowMsg(self, title, msg):
""""""
dlg = wx.MessageDialog(None, msg, title, wx.OK | wx.ICON_QUESTION)
dlg.ShowModal()
dlg.Destroy()
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
frame.Show()
app.MainLoop()
Solution 2:
I will make a stab at this, even if the answer seems too direct. I would set a property in the enclosing frame that flags whether the Radio Button has been clicked or not. Then when OnRun
is called check that property. Should it be in the wrong state, call the MessageDialog and abort/pause/modify the OnRun
.
EDIT Here is what I mean, a trivial example with two buttons, neither of which will lead to further action unless a user agreement is clicked.
import wx
classButtonFrame(wx.Frame):
def__init__(self):
wx.Frame.__init__(self, None, -1, 'Button Example',
size=(300, 100))
panel = wx.Panel(self, -1)
self.radio = wx.RadioButton(panel, -1, "Accept user agreement", pos=(50, 10))
self.button = wx.Button(panel, -1, "Run", pos=(50, 30))
self.Bind(wx.EVT_BUTTON, self.OnRun, self.button)
self.button.SetDefault()
self.btn2 = wx.Button(panel, -1, "Walk", pos=(150, 30))
self.Bind(wx.EVT_BUTTON, self.OnWalk, self.btn2)
defOnRun(self, event):
ifnot self.CheckRadio():
return
self.button.SetLabel("Running")
defOnWalk(self, event):
ifnot self.CheckRadio():
return
self.btn2.SetLabel("Walking")
defCheckRadio(self):
accepted = self.radio.GetValue()
ifnot accepted:
dlg = wx.MessageDialog(None, 'First accept the user agreement',
'MessageDialog', wx.OK | wx.ICON_QUESTION)
result = dlg.ShowModal() # result not used in this demo
dlg.Destroy()
returnFalseelse:
returnTrueif __name__ == '__main__':
app = wx.PySimpleApp()
frame = ButtonFrame()
frame.Show()
app.MainLoop()
Code is adapted from Listing 7.11 of wxPython in Action. I hope this helps, if you have not already solved this n the time that has passed.
Solution 3:
You can create your own MessageDialog (inheriting), or you can use functools.partial/lambda to pass an additional argument to the event handler:
self.Bind(wx.MY_EVENT, lambda evt: self.OnEventX(evt, handler=foo), id=12)
Post a Comment for "Call Functions From Within A Wxpython Event Handler"