1 # 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
3 # o Updated for wx namespace
4 # o There are issues using the wx namespace within the xrc code.
6 # 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
8 # o Error report: "Error: No handler found for XML node 'object',
9 # class 'wx.StaticText'!"; no text shows on panel.
15 #----------------------------------------------------------------------
17 resourceText
= r
'''<?xml version="1.0"?>
20 <!-- Notice that the class is NOT a standard wx class -->
22 <object class="MyBluePanel" name="MyPanel">
24 <object class="wx.StaticText" name="label1">
25 <label>This blue panel is a class derived from wx.Panel,\nand is loaded by a custom XmlResourceHandler.</label>
32 #----------------------------------------------------------------------
34 class MyBluePanel(wx
.Panel
):
35 def __init__(self
, parent
, id, pos
, size
, style
, name
):
36 wx
.Panel
.__init
__(self
, parent
, id, pos
, size
, style
, name
)
38 # This is the little bit of customization that we do for this
39 # silly example. It could just as easily have been done in
41 self
.SetBackgroundColour("BLUE")
42 self
.SetForegroundColour("WHITE")
45 # To do it the more complex way, (see below) we need to write the
46 # class a little differently... This could obviously be done with a
47 # single class, but I wanted to make separate ones to make clear what
48 # the different requirements are.
49 class PreMyBluePanel(wx
.Panel
):
54 def Create(self
, parent
, id, pos
, size
, style
, name
):
55 wx
.Panel
.Create(self
, parent
, id, pos
, size
, style
, name
)
56 self
.SetBackgroundColour("BLUE")
57 self
.SetForegroundColour("WHITE")
60 #----------------------------------------------------------------------
62 class MyBluePanelXmlHandler(xrc
.XmlResourceHandler
):
64 xrc
.XmlResourceHandler
.__init
__(self
)
65 # Specify the styles recognized by objects of this type
66 self
.AddStyle("wx.NO_3D", wx
.NO_3D
);
67 self
.AddStyle("wx.TAB_TRAVERSAL", wx
.TAB_TRAVERSAL
);
68 self
.AddStyle("wx.WS_EX_VALIDATE_RECURSIVELY", wx
.WS_EX_VALIDATE_RECURSIVELY
);
69 self
.AddStyle("wx.CLIP_CHILDREN", wx
.CLIP_CHILDREN
);
70 self
.AddWindowStyles();
72 # This method and the next one are required for XmlResourceHandlers
73 def CanHandle(self
, node
):
74 return self
.IsOfClass(node
, "MyBluePanel")
76 def DoCreateResource(self
):
77 # NOTE: wxWindows can be created in either a single-phase or
78 # in a two-phase way. Single phase is what you normally do,
79 # and two-phase creates the instnace first, and then later
80 # creates the actual window when the Create method is called.
81 # (In wxPython the first phase is done using the wxPre*
82 # function, for example, wxPreFrame, wxPrePanel, etc.)
84 # wxXmlResource supports either method, a premade instance can
85 # be created and populated by xrc using the appropriate
86 # LoadOn* method (such as LoadOnPanel) or xrc can create the
87 # instance too, using the Load* method. However this makes
88 # the handlers a bit more complex. If you can be sure that a
89 # particular class will never be loaded using a pre-existing
90 # instance, then you can make the handle much simpler. I'll
91 # show both methods below.
94 # The simple method assumes that there is no existing
95 # instance. Be sure of that with an assert.
96 assert self
.GetInstance() is None
98 # Now create the object
99 panel
= MyBluePanel(self
.GetParentAsWindow(),
103 self
.GetStyle("style", wx
.TAB_TRAVERSAL
),
107 # When using the more complex (but more flexible) method
108 # the instance may already have been created, check for it
109 panel
= self
.GetInstance()
111 # if not, then create the instance (but not the window)
112 panel
= PreMyBluePanel()
114 # Now call the panel's Create method to actually create the window
115 panel
.Create(self
.GetParentAsWindow(),
119 self
.GetStyle("style", wx
.TAB_TRAVERSAL
),
123 # These two things should be done in either case:
124 # Set standard window attributes
125 self
.SetupWindow(panel
)
126 # Create any child windows of this node
127 self
.CreateChildren(panel
)
132 #----------------------------------------------------------------------
135 class TestPanel(wx
.Panel
):
136 def __init__(self
, parent
, log
):
138 wx
.Panel
.__init
__(self
, parent
, -1)
140 # make the components
141 label
= wx
.StaticText(self
, -1, "The lower panel was built from this XML:")
142 label
.SetFont(wx
.Font(12, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
))
144 text
= wx
.TextCtrl(self
, -1, resourceText
,
145 style
=wx
.TE_READONLY|wx
.TE_MULTILINE
)
146 text
.SetInsertionPoint(0)
148 line
= wx
.StaticLine(self
, -1)
151 res
= xrc
.EmptyXmlResource()
152 res
.InsertHandler(MyBluePanelXmlHandler())
153 res
.LoadFromString(resourceText
)
155 # Now create a panel from the resource data
156 panel
= res
.LoadObject(self
, "MyPanel", "MyBluePanel")
159 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
160 sizer
.Add(label
, 0, wx
.EXPAND|wx
.TOP|wx
.LEFT
, 5)
161 sizer
.Add(text
, 1, wx
.EXPAND|wx
.ALL
, 5)
162 sizer
.Add(line
, 0, wx
.EXPAND
)
163 sizer
.Add(panel
, 1, wx
.EXPAND|wx
.ALL
, 5)
166 self
.SetAutoLayout(True)
169 #----------------------------------------------------------------------
171 def runTest(frame
, nb
, log
):
172 win
= TestPanel(nb
, log
)
175 #----------------------------------------------------------------------
179 overview
= """<html><body>
180 <h2><center>wxXmlResourceHandler</center></h2>
182 Deriving a class from wxXmlResourceHandler allows you to specify your
183 own classes in XRC resources, and your handler class will then be used
184 to create instances of that class when the resource is loaded.
191 if __name__
== '__main__':
194 run
.main(['', os
.path
.basename(sys
.argv
[0])])