tags:

views:

518

answers:

2

My top-level window needs to know when the internal state of a custom control changes so it can update various other parts of the GUI. How do I generate a custom event in the control, so it can propagate and be handled by the top-level window?

+1  A: 

In order to propagate, the event has to be a wx.CommandEvent. (See the wxWidgets event handling overview for details about propagation.) More specifically, it should be a wx.PyCommandEvent, which is Python-aware and is able to transport its Python bits safely through the wxWidgets event system and have them still be there when the event handler is invoked.

Define your custom event type as follows:

EVT_QUANTITY_CHANGED = wx.PyEventBinder(wx.NewEventType(), 1)

You probably want to do this at the module level, although it may in some circumstances be desirable to do this in the __init__ method of your control.

The control can now generate an event as follows:

event = wx.PyCommandEvent(EVT_QUANTITY_CHANGED.typeId, self.GetId())
self.GetEventHandler().ProcessEvent(event)

The top-level window can bind and handle the event in the usual way:

self.Bind(mycontrol.EVT_QUANTITY_CHANGED, self.OnQuantityChanged)
Vebjorn Ljosa
+1  A: 

I know this is an old question, but there is a newer, slightly nicer, way to do this in wxPython. Paraphrased from http://wiki.wxpython.org/CustomEventClasses and the above:

To define the event:

import wx.lib.newevent
QuantityChangedEvent, EVT_QUANTITY_CHANGED = wx.lib.newevent.NewCommandEvent()

To generate an event:

event = QuantityChangedEvent(self.GetId())
self.GetEventHandler().ProcessEvent(event)
# or ...
#wx.PostEvent(self, event)

Binding the event remains the same.

Alan Briolat