]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/wxXmlResourceHandler.py
Added wxXmlResourceHandler to wxPython and enabled it's virtuals to be
[wxWidgets.git] / wxPython / demo / wxXmlResourceHandler.py
1
2 from wxPython.wx import *
3 from wxPython.xrc import *
4
5 #----------------------------------------------------------------------
6
7 resourceText = r'''<?xml version="1.0"?>
8 <resource>
9
10 <!-- Notice that the class is NOT a standard wx class -->
11
12 <object class="MyBluePanel" name="MyPanel">
13 <size>200,100</size>
14 <object class="wxStaticText" name="lable1">
15 <label>This blue panel is a class derived from wxPanel,\nand is loaded by a custom wxXmlResourceHandler.</label>
16 <pos>10,10</pos>
17 </object>
18 </object>
19 </resource>
20 '''
21
22 #----------------------------------------------------------------------
23
24 class MyBluePanel(wxPanel):
25 def __init__(self, parent, id, pos, size, style, name):
26 wxPanel.__init__(self, parent, id, pos, size, style, name)
27
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
30 # the resource.
31 self.SetBackgroundColour("BLUE")
32
33
34 # To do it the more complex way, (see below) we need to write the
35 # class a little differently... This could obviously be done with a
36 # single class, but I wanted to make separate ones to make clear what
37 # the different requirements are.
38 class PreMyBluePanel(wxPanel):
39 def __init__(self):
40 p = wxPrePanel()
41 self.this = p.this
42
43 def Create(self, parent, id, pos, size, style, name):
44 wxPanel.Create(self, parent, id, pos, size, style, name)
45 self.SetBackgroundColour("BLUE")
46
47 #----------------------------------------------------------------------
48
49 class MyBluePanelXmlHandler(wxXmlResourceHandler):
50 def __init__(self):
51 wxXmlResourceHandler.__init__(self)
52 # Specify the styles recognized by objects of this type
53 self.AddStyle("wxNO_3D", wxNO_3D);
54 self.AddStyle("wxTAB_TRAVERSAL", wxTAB_TRAVERSAL);
55 self.AddStyle("wxWS_EX_VALIDATE_RECURSIVELY", wxWS_EX_VALIDATE_RECURSIVELY);
56 self.AddStyle("wxCLIP_CHILDREN", wxCLIP_CHILDREN);
57 self.AddWindowStyles();
58
59 # This method and the next one are required for XmlResourceHandlers
60 def CanHandle(self, node):
61 return self.IsOfClass(node, "MyBluePanel")
62
63 def DoCreateResource(self):
64 # NOTE: wxWindows can be created in either a single-phase or
65 # in a two-phase way. Single phase is what you normally do,
66 # and two-phase creates the instnace first, and then later
67 # creates the actual window when the Create method is called.
68 # (In wxPython the first phase is done using the wxPre*
69 # function, for example, wxPreFrame, wxPrePanel, etc.)
70 #
71 # wxXmlResource supports either method, a premade instance can
72 # be created and populated by xrc using the appropriate
73 # LoadOn* method (such as LoadOnPanel) or xrc can create the
74 # instance too, using the Load* method. However this makes
75 # the handlers a bit more complex. If you can be sure that a
76 # particular class will never be loaded using a pre-existing
77 # instance, then you can make the handle much simpler. I'll
78 # show both methods below.
79
80 if 0:
81 # The simple method assumes that there is no existing
82 # instance. Be sure of that with an assert.
83 assert self.GetInstance() is None
84
85 # Now create the object
86 panel = MyBluePanel(self.GetParentAsWindow(),
87 self.GetID(),
88 self.GetPosition(),
89 self.GetSize(),
90 self.GetStyle("style", wxTAB_TRAVERSAL),
91 self.GetName()
92 )
93 else:
94 # When using the more complex (but more flexible) method
95 # the instance may already have been created, check for it
96 panel = self.GetInstance()
97 if panel is None:
98 # if not, then create the instance (but not the window)
99 panel = PreMyBluePanel()
100
101 # Now call the panel's Create method to actually create the window
102 panel.Create(self.GetParentAsWindow(),
103 self.GetID(),
104 self.GetPosition(),
105 self.GetSize(),
106 self.GetStyle("style", wxTAB_TRAVERSAL),
107 self.GetName()
108 )
109
110 # These two things should be done in either case:
111 # Set standard window attributes
112 self.SetupWindow(panel)
113 # Create any child windows of this node
114 self.CreateChildren(panel)
115
116 return panel
117
118
119 #----------------------------------------------------------------------
120
121
122 class TestPanel(wxPanel):
123 def __init__(self, parent, log):
124 self.log = log
125 wxPanel.__init__(self, parent, -1)
126
127 # make the components
128 label = wxStaticText(self, -1, "The lower panel was built from this XML:")
129 label.SetFont(wxFont(12, wxSWISS, wxNORMAL, wxBOLD))
130
131 text = wxTextCtrl(self, -1, resourceText,
132 style=wxTE_READONLY|wxTE_MULTILINE)
133 text.SetInsertionPoint(0)
134
135 line = wxStaticLine(self, -1)
136
137 # Load the resource
138 res = wxEmptyXmlResource()
139 res.InsertHandler(MyBluePanelXmlHandler())
140 res.LoadFromString(resourceText)
141
142 # Now create a panel from the resource data
143 panel = res.LoadObject(self, "MyPanel", "MyBluePanel")
144
145 # and do the layout
146 sizer = wxBoxSizer(wxVERTICAL)
147 sizer.Add(label, 0, wxEXPAND|wxTOP|wxLEFT, 5)
148 sizer.Add(text, 1, wxEXPAND|wxALL, 5)
149 sizer.Add(line, 0, wxEXPAND)
150 sizer.Add(panel, 1, wxEXPAND|wxALL, 5)
151
152 self.SetSizer(sizer)
153 self.SetAutoLayout(true)
154
155
156 #----------------------------------------------------------------------
157
158 def runTest(frame, nb, log):
159 win = TestPanel(nb, log)
160 return win
161
162 #----------------------------------------------------------------------
163
164
165
166 overview = """<html><body>
167 <h2><center>wxXmlResourceHandler</center></h2>
168
169 Deriving a class from wxXmlResourceHandler allows you to specify your
170 own classes in XRC resources, and your handler class will then be used
171 to create instances of that class when the resource is loaded.
172
173 </body></html>
174 """
175
176
177
178 if __name__ == '__main__':
179 import sys,os
180 import run
181 run.main(['', os.path.basename(sys.argv[0])])
182