Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wxPython: Calling an event manually

Tags:

How can I call a specific event manually from my own code?

like image 691
Ram Rachum Avatar asked Apr 14 '09 14:04

Ram Rachum


3 Answers

Old topic, but I think I've got this figured out after being confused about it for a long time, so if anyone else comes through here looking for the answer, this might help.

To manually post an event, you can use

self.GetEventHandler().ProcessEvent(event)

(wxWidgets docs here, wxPython docs here)

or

wx.PostEvent(self.GetEventHandler(), event)

(wxWidgets docs, wxPython docs)

where event is the event you want to post. Construct the event with e.g.

wx.PyCommandEvent(wx.EVT_BUTTON.typeId, self.GetId())

if you want to post a EVT_BUTTON event. Making it a PyCommandEvent means that it will propagate upwards; other event types don't propagate by default.

You can also create custom events that can carry whatever data you want them to. Here's an example:

myEVT_CUSTOM = wx.NewEventType()
EVT_CUSTOM = wx.PyEventBinder(myEVT_CUSTOM, 1)

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id):
        wx.PyCommandEvent.__init__(self, evtType, id)
        myVal = None

    def SetMyVal(self, val):
        self.myVal = val

    def GetMyVal(self):
        return self.myVal

(I think I found this code in a mailing list archive somewhere, but I can't seem to find it again. If this is your example, thanks! Please add a comment and take credit for it!)

So now, to Post a custom event:

event = MyEvent(myEVT_CUSTOM, self.GetId())
event.SetMyVal('here is some custom data')
self.GetEventHandler().ProcessEvent(event)

and you can bind it just like any other event

self.Bind(EVT_CUSTOM, self.on_event)

and get the custom data in the event handler

def on_event(self, e):
    data = e.GetMyVal()
    print 'custom data is: {0}'.format(data)

Or include the custom data in the event constructor and save a step:

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id, val = None):
        wx.PyCommandEvent.__init__(self, evtType, id)
        self.myVal = val

etc.

Hope this is helpful to someone.

like image 178
David Avatar answered Oct 19 '22 03:10

David


I think you want wx.PostEvent.

There's also some info about posting events from other thread for long running tasks on the wxPython wiki.

like image 38
John Montgomery Avatar answered Oct 19 '22 04:10

John Montgomery


There's a simple, straightforward way to do it with recent versions of wxPython (see http://wiki.wxpython.org/CustomEventClasses):

   # create event class
   import wx.lib.newevent
   SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()

   # post it, with arbitrary data attached
   wx.PostEvent(target, SomeNewEvent(attr1=foo, attr2=bar))

   # bind it as usual
   target.Bind(EVT_SOME_NEW_EVENT, target.handler)
like image 35
Dan Lenski Avatar answered Oct 19 '22 03:10

Dan Lenski