subclassing wxMenuBar...
Tom Jenkins
tjenkins at devis.com
Tue Jun 5 09:27:57 EDT 2001
Tom Jenkins <tjenkins at devis.com> wrote in message news:<mailman.991661708.12433.python-list at python.org>...
> Bjorn Pettersen wrote:
>
> > I was stepping through the wxPython tutorial, and came across the part
> > where they're creating the menus. It seemed like a good idea to put the
> > menu definition in a datafile instead of specifying it programatically,
> > so I though it would be a good chance to get some xml experience too...
> >
[snip]
>
> Well I wouldn't subclass wxMenuBar; instead I'd create a helper class
> that would handle reading the xml and loading it into the wxMenuBar. I
> took your code and changed it to work as a helper. Along the way I
> added some functionality.
[snip]
Err... well it looks like the mailing list -> newsgroup bridge
stripped out the attachment that contained the code for the helper
class. So let me follow up by putting it directly in the message
<grin>
#----------------------------------
'''
XMLMenuLoader: Class to handle loading a wxMenuBar with menu items
defined in XML
author: Tom Jenkins <tjenkins at devis.com>
based on code by Bjorn Pettersen <BPettersen at NAREX.com>
#*TODO*: refactor load into base class that handles loading the menu
in another way so we can have ListMenuLoader, StreamMenuLoader, etc...
'''
from xml.dom import minidom
from wxPython.wx import *
def filterText(nodelist):
return [ x for x in nodelist if x.nodeType != x.TEXT_NODE ]
class XMLMenuLoader:
def __init__(self, filename, wxMenuBar = None):
'''Save the filename and menubar to use'''
self._filename = filename
self.setMenuBar(wxMenuBar)
def setMenuBar(self, wxMenuBar = None):
''' set the menubar property to the given menubar
wxMenuBar -> the root menubar of the frame'''
self._wxMenuBar = wxMenuBar
def menuBar(self):
'''Return the stored menubar'''
return self._wxMenuBar
def load(self, wxMenuBar = None, controller = None):
'''Load the menubar with the menu items stored in XML format in
the instance's filename property
wxMenuBar -> the root menubar of the frame; if given will become
the instances new menubar property
controller -> the class instance that will receive any callbacks
stored in the menu items' callback attribute
'''
if wxMenuBar != None:
self.setMenuBar(wxMenuBar)
menubar = minidom.parse(self._filename)
# loop over and process all of the menu elements in the menubar
for menu in menubar.getElementsByTagName('menu'):
menuName = menu.attributes['name'].nodeValue.replace('_', '&')
wxmenu = wxMenu()
for menuItem in filterText(menu.childNodes):
if menuItem.tagName == 'menuitem':
attrs = menuItem.attributes
idTag = int( attrs['id'].nodeValue )
name = attrs['name'].nodeValue.replace('_', '&')
info = attrs['info'].nodeValue
wxmenu.Append(idTag, name, info)
# only load the callbacks if there is a controller
if controller:
try:
callback = attrs['callback'].nodeValue
handler = getattr(controller, callback, None)
if handler:
EVT_MENU(controller, idTag, handler)
except KeyError, ex:
# didn't have a callback attribute - skip
#*TODO*: check if there is a better way; maybe a has_key test?
pass
elif menuItem.tagName == 'separator':
wxmenu.AppendSeparator()
self.menuBar().Append(wxmenu, menuName)
#----------------------------------
>
> Thanks for the initial post Bjorn, I had fun working on this...
Didn't-have-fun-getting-the-code-out-to-you-though-ly, yours
Tom
More information about the Python-list
mailing list