5 #---------------------------------------------------------------------- 
   7 resourceText 
= r
'''<?xml version="1.0"?> 
  10 <!-- Notice that the class is NOT a standard wx class --> 
  12 <object class="MyBluePanel" name="MyPanel"> 
  14     <object class="wxStaticText" name="label1"> 
  15         <label>This blue panel is a class derived from wx.Panel,\nand is loaded by a custom XmlResourceHandler.</label> 
  22 #---------------------------------------------------------------------- 
  24 class MyBluePanel(wx
.Panel
): 
  25     def __init__(self
, parent
, id, pos
, size
, style
, name
): 
  26         wx
.Panel
.__init
__(self
, parent
, id, pos
, size
, style
, name
) 
  28         # This is the little bit of customization that we do for this 
  29         # silly example.  It could just as easily have been done in 
  31         self
.SetBackgroundColour("BLUE") 
  32         self
.SetForegroundColour("WHITE") 
  35 # To do it the more complex way, (see below) we need to write the 
  36 # class a little differently...  This could obviously be done with a 
  37 # single class, but I wanted to make separate ones to make clear what 
  38 # the different requirements are. 
  39 class PreMyBluePanel(wx
.Panel
): 
  44     def Create(self
, parent
, id, pos
, size
, style
, name
): 
  45         wx
.Panel
.Create(self
, parent
, id, pos
, size
, style
, name
) 
  46         self
.SetBackgroundColour("BLUE") 
  47         self
.SetForegroundColour("WHITE") 
  50 #---------------------------------------------------------------------- 
  52 class MyBluePanelXmlHandler(xrc
.XmlResourceHandler
): 
  54         xrc
.XmlResourceHandler
.__init
__(self
) 
  55         # Specify the styles recognized by objects of this type 
  56         self
.AddStyle("wx.NO_3D", wx
.NO_3D
); 
  57         self
.AddStyle("wx.TAB_TRAVERSAL", wx
.TAB_TRAVERSAL
); 
  58         self
.AddStyle("wx.WS_EX_VALIDATE_RECURSIVELY", wx
.WS_EX_VALIDATE_RECURSIVELY
); 
  59         self
.AddStyle("wx.CLIP_CHILDREN", wx
.CLIP_CHILDREN
); 
  60         self
.AddWindowStyles(); 
  62     # This method and the next one are required for XmlResourceHandlers 
  63     def CanHandle(self
, node
): 
  64         return self
.IsOfClass(node
, "MyBluePanel") 
  66     def DoCreateResource(self
): 
  67         # NOTE: wxWindows can be created in either a single-phase or 
  68         # in a two-phase way.  Single phase is what you normally do, 
  69         # and two-phase creates the instnace first, and then later 
  70         # creates the actual window when the Create method is called. 
  71         # (In wxPython the first phase is done using the wxPre* 
  72         # function, for example, wxPreFrame, wxPrePanel, etc.) 
  74         # wxXmlResource supports either method, a premade instance can 
  75         # be created and populated by xrc using the appropriate 
  76         # LoadOn* method (such as LoadOnPanel) or xrc can create the 
  77         # instance too, using the Load* method.  However this makes 
  78         # the handlers a bit more complex.  If you can be sure that a 
  79         # particular class will never be loaded using a pre-existing 
  80         # instance, then you can make the handle much simpler.  I'll 
  81         # show both methods below. 
  84             # The simple method assumes that there is no existing 
  85             # instance.  Be sure of that with an assert. 
  86             assert self
.GetInstance() is None 
  88             # Now create the object 
  89             panel 
= MyBluePanel(self
.GetParentAsWindow(), 
  93                                 self
.GetStyle("style", wx
.TAB_TRAVERSAL
), 
  97             # When using the more complex (but more flexible) method 
  98             # the instance may already have been created, check for it 
  99             panel 
= self
.GetInstance() 
 101                 # if not, then create the instance (but not the window) 
 102                 panel 
= PreMyBluePanel() 
 104             # Now call the panel's Create method to actually create the window 
 105             panel
.Create(self
.GetParentAsWindow(), 
 109                          self
.GetStyle("style", wx
.TAB_TRAVERSAL
), 
 113         # These two things should be done in either case: 
 114         # Set standard window attributes 
 115         self
.SetupWindow(panel
) 
 116         # Create any child windows of this node 
 117         self
.CreateChildren(panel
) 
 122 #---------------------------------------------------------------------- 
 125 class TestPanel(wx
.Panel
): 
 126     def __init__(self
, parent
, log
): 
 128         wx
.Panel
.__init
__(self
, parent
, -1) 
 130         # make the components 
 131         label 
= wx
.StaticText(self
, -1, "The lower panel was built from this XML:") 
 132         label
.SetFont(wx
.Font(12, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
)) 
 134         text 
= wx
.TextCtrl(self
, -1, resourceText
, 
 135                           style
=wx
.TE_READONLY|wx
.TE_MULTILINE
) 
 136         text
.SetInsertionPoint(0) 
 138         line 
= wx
.StaticLine(self
, -1) 
 141         res 
= xrc
.EmptyXmlResource() 
 142         res
.InsertHandler(MyBluePanelXmlHandler()) 
 143         res
.LoadFromString(resourceText
) 
 145         # Now create a panel from the resource data 
 146         panel 
= res
.LoadObject(self
, "MyPanel", "MyBluePanel") 
 149         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 150         sizer
.Add(label
, 0, wx
.EXPAND|wx
.TOP|wx
.LEFT
, 5) 
 151         sizer
.Add(text
, 1, wx
.EXPAND|wx
.ALL
, 5) 
 152         sizer
.Add(line
, 0, wx
.EXPAND
) 
 153         sizer
.Add(panel
, 1, wx
.EXPAND|wx
.ALL
, 5) 
 156         self
.SetAutoLayout(True) 
 159 #---------------------------------------------------------------------- 
 161 def runTest(frame
, nb
, log
): 
 162     win 
= TestPanel(nb
, log
) 
 165 #---------------------------------------------------------------------- 
 169 overview 
= """<html><body> 
 170 <h2><center>wx.XmlResourceHandler</center></h2> 
 172 Deriving a class from wx.XmlResourceHandler allows you to specify your 
 173 own classes in XRC resources, and your handler class will then be used 
 174 to create instances of that class when the resource is loaded. 
 181 if __name__ 
== '__main__': 
 184     run
.main(['', os
.path
.basename(sys
.argv
[0])])