Skip to content Skip to sidebar Skip to footer

Call Functions From Within A Wxpython Event Handler

I'm struggling to find a way to use function from within a wxPython event handler function. Say I have a button that when clicked it runs a function called OnRun using an event ha

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"