I realize I should have said “make the widgets pass themselves in” – when I bind a default command to the widget’s event, I always pass the calling widget to the command so that the handlers don’t need any special info to figure out which widget triggered the handler. I can ignore the info if needed, but i’s usually handy and it saves a lot of state management.
As for event splitting:
The tricky bit is that in vanilla maya GUI you only get events that Maya gives you – if Maya wants to fire the event it will, and the handler won’t know why (and conversely if Maya doesn’t fire it you won’t know that either: I constantly get pissed that there’s no KeyDown event in maya.cmds widgets, although to date I have resisted the temptation to go around cmds and get the underlying widget to try to find the QT event directly… that way lies madness).
On the other hand there is nothing to stop you from creating your own events and firing them when you want to. It’s pretty good practice to publish the events you want to support and then let the consumers decide what to do. Here’s a pseudocode example of the way I’d do it in mGui:
def __init__(self, key, *args, **kwargs):
super(MyCustomList, self).init(key, *args, **kwargs):
self.ListCleared = Event()
self.removeAll = True # mGui for cmds.textScrollList(self.widget, e=True, ra=True)
# and somewhere else:
example = Window(None)
col = ColumnLayout(None)
the_list = MyCustomList(None)
def when_list_is_cleared (*args, **kwargs):
# in mGUi all events fire with a keyword that
# id's the object which fired the callback...
print kwargs['sender'], "was cleared"
the_list.ListCleared += when_list_is_cleared
I do something like this in https://github.com/theodox/mGui/blob/master/mGui/observable.py where I have some classes that are basically just lists which emit events when items are added, removed, sorted or cleared. Since the handlers all have the same signature, some callers might subscribe to both SelectionChanged and ListCleared and do different things, while other callers could attach to only one of them, or you could attach the same handler to both events.
Since the event is a persistent object, you could easily add a flag to suppress the event temporarily – so if clearing the list fired an event you didn’t want you could do something like
self.SelectionChange.enabled = False
self.removeAll = True
self.SellctionChange.enabled = True
and nobody would ever receive the SelectionChanged event. It’d probably be a good idea to make that a context manager so you ddin’t inadvertently turn the event off and forget it… mGui.Events does not currently do this, but it would be trivial to add