Hi Gary,
I have been using wxPython for a number of years, and am basically very happy, but I continually troubled by not having an acceptable doc/view architecture.
The existing code, which I can’t tell if it is being actively used or maintained, requires an explicit ProcessEvent method, with a long switch table. This seems like a huge kludge to me. Enough so, that I have never really learned or used it. It is neither Pythonic or C++'onic as far as I am concerned. Apparently, this is done because wxPython does not have a virtual ProcessEvent function. I don’t really understand this, as the function is referred to as being virtual on the C++ side, but I accept the statement as being true. I have not dug throught he C++ code sufficiently to figure out why.
Actually, in my experience I’ve found that the ProcessEvent table approach doesn’t work very well anyway. It’s attempting to workaround the issue that you can only have one registered event handler for a particular ID at any given time, while in a doc-view framework you often need a stack of event handlers. Since wx’s event system doesn’t maintain a stack like this, pydocview basically calls ProcessEvent on every document and view until it finds one that will handle the event. Besides being kind of hard to grep, I’ve seen this take up lots of processing time in a large app - sometimes during an update UI event for a menubar/toolbar, ProcessUpdateUIEvent will literally get called 1000 times. On slower machines, I’ve seen this cause an app to eat up anywhere from 5% to 30% of CPU while idle.
I’ve devised an alternate solution. What it does is creates a stack of event handlers, and you basically just push the handler you want to the top of the stack and pop it when the view loses focus (and thus should no longer handle the event). For example, the current view pushes events on the stack when it gains focus, and then removes them when it loses focus. This way your ‘default’ event handler is never lost, and you don’t have to call ProcessEvent dozens or even hundreds of times to find the event handler you need. See the AppEventHandlerMixin here:
Basically, add this mixin to your wx.App class, then call app.AddHandlerForID on SetFocus (or Activate for TLWs) and call app.RemoveHandlerForID on KillFocus (or when becoming inactive for TLWs). I know Cody is using it in Editra, and so far he hasn’t yelled at me so it appears the approach is sound. The downside to this approach is that it doesn’t auto-register all the standard IDs like docview does, but if you look at the AppEventManager class in that file, I was trying to come up with an approach for that, too.
I have wanted to take things further and improve other aspects of the docview framework as well (e.g. support the idea of a common menubar on Mac), but I have been busy with wxWebKit work and have not yet found a way to get paid to work fulltime on wxPython. Sadly, that’s even difficult for Robin to do!
Thanks,
Kevin
···
On Jan 16, 2008, at 2:11 PM, Gary Hubbard wrote:
My question is if the same thing could be accomplished by using PushEventHandler(), effectively adding another event handling layer between each existing layer. I am willing to make this work and perform the required code patches myself, but don’t really want to start understanding things well enough if someone more knowledgeable about this than I indicates it can’t be done for some reason, or that.
I am open to any and all other suggestions, including other equivalent frameworks.
Gary