I’m using the FlatNotebook widget in a program I’m developing and am trying to transition my code to use XRC. To do this I currently need to write my own XmlResourceHandler for XRC to use when loading my resource file. I built a FlatNotebookHandler class to do this (fashioned after the Notebook handler I found in the wxWidgets code) but am having problems getting it to work. I’ve stripped this down to a (somewhat) small example program showing what I’ve got and what’s not working. Hopefully one of the very smart people that subscribe to this list can help me target what I’m not doing correctly. Enough chat, here’s the code (my platform specifics are included in the output text included below the code):
##BEGIN CODE#################################
import wx
from wx import xrc
from wx.lib import flatnotebook as fnb
DEBUG = True
xrc_source = “”"\
<?xml version=" 1.0" ?> wxVERTICAL Some multiline text. wxTE_MULTILINE <option>1</option>
<flag>wxEXPAND</flag>
</object>
</object>
</object>
</object>
<object class="flatnotebookpage">
<object class="wxPanel">
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxTextCtrl">
<value>Some multiline
text.
wxTE_MULTILINE
<option>1</option>
<flag>wxEXPAND</flag>
</object>
</object>
</object>
</object>
<style>FNB_NO_X_BUTTON|FNB_VC8</style>
</object>
"""
class FlatNotebookXmlHandler(xrc.XmlResourceHandler):
def init(self):
xrc.XmlResourceHandler.init(self)
self.AddWindowStyles()
self.AddStyle("FNB_VC71", fnb.FNB_VC71)
self.AddStyle("FNB_FANCY_TABS", fnb.FNB_FANCY_TABS)
self.AddStyle("FNB_TABS_BORDER_SIMPLE", fnb.FNB_TABS_BORDER_SIMPLE)
self.AddStyle("FNB_NO_X_BUTTON", fnb.FNB_NO_X_BUTTON)
self.AddStyle("FNB_NO_NAV_BUTTONS", fnb.FNB_NO_NAV_BUTTONS)
self.AddStyle("FNB_MOUSE_MIDDLE_CLOSES_TABS", fnb.FNB_MOUSE_MIDDLE_CLOSES_TABS)
self.AddStyle("FNB_BOTTOM", fnb.FNB_BOTTOM)
self.AddStyle("FNB_NODRAG", fnb.FNB_NODRAG)
self.AddStyle("FNB_VC8", fnb.FNB_VC8
)
self.AddStyle(“FNB_FF2”, fnb.FNB_FF2)
self.AddStyle(“FNB_X_ON_TAB”, fnb.FNB_X_ON_TAB)
self.AddStyle(“FNB_BACKGROUND_GRADIENT”, fnb.FNB_BACKGROUND_GRADIENT)
self.AddStyle(“FNB_COLORFUL_TABS”, fnb.FNB_COLORFUL_TABS)
self.AddStyle(“FNB_DCLICK_CLOSES_TABS”, fnb.FNB_DCLICK_CLOSES_TABS)
self.AddStyle(“FNB_SMART_TABS”, fnb.FNB_SMART_TABS
)
self.AddStyle(“FNB_DROPDOWN_TABS_LIST”, fnb.FNB_DROPDOWN_TABS_LIST)
self.AddStyle(“FNB_ALLOW_FOREIGN_DND”, fnb.FNB_ALLOW_FOREIGN_DND)
self.AddStyle(“FNB_HIDE_ON_SINGLE_TAB”, fnb.FNB_HIDE_ON_SINGLE_TAB)
self.isInside = False
self.fnb = None
def CanHandle(self, node):
if DEBUG:
if self.IsOfClass(node, "FlatNotebook"):
print "XmlResource:CanHandle called with FlatNotebook node"
elif self.IsOfClass(node, "flatnotebookpage"):
print "XmlResource:CanHandle called with flatnotebookpage node"
else:
print "XmlResource:CanHandle called with unsupported node type"
retVal = ((not self.isInside and self.IsOfClass(node, "FlatNotebook") or
self.isInside and self.IsOfClass(node, "flatnotebookpage")))
if DEBUG:
print "XmlResource:CanHandle returning " + str(retVal)
return retVal
def DoCreateResource(self):
if self.GetClass() == "flatnotebookpage":
if DEBUG:
print "XmlResource:DoCreateResource called for flatnotebookpage"
node = self.GetParamNode("object")
if not node:
node = self.GetParamNode("object_ref")
if not node:
wx.LogError("Error in resource: no control within choicebook's <page> tag.")
return None
old_isInside = self.isInside
self.isInside = False
wnd = self.CreateResFromNode(node, self.fnb, None)
self.isInside = old_isInside
if not type(wnd, wx.Window):
wx.LogError("Error in resource.")
return wnd
self.fnb.AddPage(wnd, self.GetText("label"), self.GetBool("selected"))
if self.HasParam("bitmap"):
bmp = self.GetBitmap("bitmap", wx.ART_OTHER)
imgList = self.fnb.GetImageList()
if not imgList:
imgList = wx.ImageList(bmp.GetWidth(), bmp.GetHeight())
self.fnb.AssignImageList(imgList)
imgIndex = imgList.Add(bmp)
self.fnb.SetPageImage(self.fnb.GetPageCount
()-1, imgIndex)
return wnd
elif self.GetClass() == "FlatNotebook":
if DEBUG:
print "XmlResource:DoCreateResource called for FlatNotebook"
assert self.GetInstance() is None
book = fnb.FlatNotebook(self.GetParentAsWindow(),
self.GetID(),
self.GetPosition(),
self.GetSize(),
self.GetStyle("style"),
self.GetName())
self.SetupWindow(book)
oldBook = self.fnb
oldInside = self.isInside
self.fnb = book
self.isInside = True
self.CreateChildren(book, True)
self.isInside = oldInside
self.fnb = oldBook
return book
else:
if DEBUG:
print "XmlResource:DoCreateResource called for unknown type"
class MyApp(wx.App):
def OnInit(self):
self.res = xrc.EmptyXmlResource()
self.res.InsertHandler(FlatNotebookXmlHandler())
self.res.LoadFromString(xrc_source)
self.init_frame()
return True
def init_frame(self):
self.frame = self.res.LoadFrame(None, 'mainFrame')
self.frame.Show()
if name == ‘main’:
if DEBUG:
import sys
print "Starting test application on the following platform:"
print "\tPython: " + sys.version
print "\twx: " + wx.version
()
print
app = MyApp(False)
app.MainLoop()
##End Code#################################
The result of running this code (at least on my machine) provides a frame, but with none of the notebook’s pages populated. Indeed, looking at the debugging print statements, you can see that the resource handler sees all the calls I would expect to see for the CanHandle method, but neither of the flatnotebookpage nodes result in a DoCreateResource call (even though CanHandle is seen and returns True). Here’s the debug output I get:
Starting test application on the following platform:
Python: 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)]
wx: 2.8.4.0 (msw-unicode)
XmlResource:CanHandle called with unsupported node type
XmlResource:CanHandle returning False
XmlResource:CanHandle called with FlatNotebook node
XmlResource:CanHandle returning True
XmlResource:DoCreateResource called for FlatNotebook
XmlResource:CanHandle called with flatnotebookpage node
XmlResource:CanHandle returning True
XmlResource:CanHandle called with flatnotebookpage node
XmlResource:CanHandle returning True
Any ideas?