2 from wxPython
.wx
import *
3 from wxPython
.xrc
import *
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 wxPanel,\nand is loaded by a custom wxXmlResourceHandler.</label>
22 #----------------------------------------------------------------------
24 class MyBluePanel(wxPanel
):
25 def __init__(self
, parent
, id, pos
, size
, style
, name
):
26 wxPanel
.__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(wxPanel
):
44 def Create(self
, parent
, id, pos
, size
, style
, name
):
45 wxPanel
.Create(self
, parent
, id, pos
, size
, style
, name
)
46 self
.SetBackgroundColour("BLUE")
47 self
.SetForegroundColour("WHITE")
50 #----------------------------------------------------------------------
52 class MyBluePanelXmlHandler(wxXmlResourceHandler
):
54 wxXmlResourceHandler
.__init
__(self
)
55 # Specify the styles recognized by objects of this type
56 self
.AddStyle("wxNO_3D", wxNO_3D
);
57 self
.AddStyle("wxTAB_TRAVERSAL", wxTAB_TRAVERSAL
);
58 self
.AddStyle("wxWS_EX_VALIDATE_RECURSIVELY", wxWS_EX_VALIDATE_RECURSIVELY
);
59 self
.AddStyle("wxCLIP_CHILDREN", wxCLIP_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", wxTAB_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", wxTAB_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(wxPanel
):
126 def __init__(self
, parent
, log
):
128 wxPanel
.__init
__(self
, parent
, -1)
130 # make the components
131 label
= wxStaticText(self
, -1, "The lower panel was built from this XML:")
132 label
.SetFont(wxFont(12, wxSWISS
, wxNORMAL
, wxBOLD
))
134 text
= wxTextCtrl(self
, -1, resourceText
,
135 style
=wxTE_READONLY|wxTE_MULTILINE
)
136 text
.SetInsertionPoint(0)
138 line
= wxStaticLine(self
, -1)
141 res
= wxEmptyXmlResource()
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
= wxBoxSizer(wxVERTICAL
)
150 sizer
.Add(label
, 0, wxEXPAND|wxTOP|wxLEFT
, 5)
151 sizer
.Add(text
, 1, wxEXPAND|wxALL
, 5)
152 sizer
.Add(line
, 0, wxEXPAND
)
153 sizer
.Add(panel
, 1, wxEXPAND|wxALL
, 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>wxXmlResourceHandler</center></h2>
172 Deriving a class from wxXmlResourceHandler 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])])