]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/XmlResourceHandler.py
Don't decref if the interpreter is not initialized, (eg. it's in its
[wxWidgets.git] / wxPython / demo / XmlResourceHandler.py
CommitLineData
8fa876ca
RD
1
2import wx
3import wx.xrc as xrc
628c7f79
RD
4
5#----------------------------------------------------------------------
6
7resourceText = r'''<?xml version="1.0"?>
8<resource>
9
10<!-- Notice that the class is NOT a standard wx class -->
11
5cd7ab8d 12<object class="MyCustomPanel" name="MyPanel">
628c7f79 13 <size>200,100</size>
95bfd958 14 <object class="wxStaticText" name="label1">
102e2b26 15 <label>This panel is a custom class derived from wx.Panel,\nand is loaded by a custom XmlResourceHandler.</label>
628c7f79
RD
16 <pos>10,10</pos>
17 </object>
18</object>
19</resource>
20'''
21
22#----------------------------------------------------------------------
23
5cd7ab8d 24class MyCustomPanel(wx.Panel):
628c7f79 25 def __init__(self, parent, id, pos, size, style, name):
8fa876ca 26 wx.Panel.__init__(self, parent, id, pos, size, style, name)
628c7f79
RD
27
28 # This is the little bit of customization that we do for this
5cd7ab8d
RD
29 # silly example.
30 self.Bind(wx.EVT_SIZE, self.OnSize)
31 t = wx.StaticText(self, -1, "MyCustomPanel")
32 f = t.GetFont()
33 f.SetWeight(wx.BOLD)
34 f.SetPointSize(f.GetPointSize()+2)
35 t.SetFont(f)
36 self.t = t
37
38 def OnSize(self, evt):
39 sz = self.GetSize()
40 w, h = self.t.GetTextExtent(self.t.GetLabel())
41 self.t.SetPosition(((sz.width-w)/2, (sz.height-h)/2))
628c7f79
RD
42
43
44# To do it the more complex way, (see below) we need to write the
45# class a little differently... This could obviously be done with a
46# single class, but I wanted to make separate ones to make clear what
47# the different requirements are.
5cd7ab8d 48class PreMyCustomPanel(wx.Panel):
628c7f79 49 def __init__(self):
8fa876ca 50 p = wx.PrePanel()
d14a1e28 51 self.PostCreate(p)
628c7f79
RD
52
53 def Create(self, parent, id, pos, size, style, name):
8fa876ca 54 wx.Panel.Create(self, parent, id, pos, size, style, name)
5cd7ab8d
RD
55 self.Bind(wx.EVT_SIZE, self.OnSize)
56 t = wx.StaticText(self, -1, "MyCustomPanel")
57 f = t.GetFont()
58 f.SetWeight(wx.BOLD)
59 f.SetPointSize(f.GetPointSize()+2)
60 t.SetFont(f)
61 self.t = t
62
63 def OnSize(self, evt):
64 sz = self.GetSize()
65 w, h = self.t.GetTextExtent(self.t.GetLabel())
66 self.t.SetPosition(((sz.width-w)/2, (sz.height-h)/2))
628c7f79
RD
67
68#----------------------------------------------------------------------
69
5cd7ab8d 70class MyCustomPanelXmlHandler(xrc.XmlResourceHandler):
628c7f79 71 def __init__(self):
8fa876ca 72 xrc.XmlResourceHandler.__init__(self)
628c7f79 73 # Specify the styles recognized by objects of this type
02b800ce
RD
74 self.AddStyle("wxNO_3D", wx.NO_3D)
75 self.AddStyle("wxTAB_TRAVERSAL", wx.TAB_TRAVERSAL)
76 self.AddStyle("wxWS_EX_VALIDATE_RECURSIVELY", wx.WS_EX_VALIDATE_RECURSIVELY)
77 self.AddStyle("wxCLIP_CHILDREN", wx.CLIP_CHILDREN)
78 self.AddWindowStyles()
628c7f79
RD
79
80 # This method and the next one are required for XmlResourceHandlers
81 def CanHandle(self, node):
5cd7ab8d 82 return self.IsOfClass(node, "MyCustomPanel")
628c7f79
RD
83
84 def DoCreateResource(self):
85 # NOTE: wxWindows can be created in either a single-phase or
86 # in a two-phase way. Single phase is what you normally do,
87 # and two-phase creates the instnace first, and then later
88 # creates the actual window when the Create method is called.
89 # (In wxPython the first phase is done using the wxPre*
90 # function, for example, wxPreFrame, wxPrePanel, etc.)
91 #
92 # wxXmlResource supports either method, a premade instance can
93 # be created and populated by xrc using the appropriate
94 # LoadOn* method (such as LoadOnPanel) or xrc can create the
95 # instance too, using the Load* method. However this makes
96 # the handlers a bit more complex. If you can be sure that a
97 # particular class will never be loaded using a pre-existing
98 # instance, then you can make the handle much simpler. I'll
99 # show both methods below.
100
361cef5f 101 if 1:
628c7f79
RD
102 # The simple method assumes that there is no existing
103 # instance. Be sure of that with an assert.
104 assert self.GetInstance() is None
105
106 # Now create the object
5cd7ab8d
RD
107 panel = MyCustomPanel(self.GetParentAsWindow(),
108 self.GetID(),
109 self.GetPosition(),
110 self.GetSize(),
111 self.GetStyle("style", wx.TAB_TRAVERSAL),
112 self.GetName()
113 )
628c7f79
RD
114 else:
115 # When using the more complex (but more flexible) method
116 # the instance may already have been created, check for it
117 panel = self.GetInstance()
118 if panel is None:
119 # if not, then create the instance (but not the window)
5cd7ab8d 120 panel = PreMyCustomPanel()
628c7f79
RD
121
122 # Now call the panel's Create method to actually create the window
123 panel.Create(self.GetParentAsWindow(),
124 self.GetID(),
125 self.GetPosition(),
126 self.GetSize(),
8fa876ca 127 self.GetStyle("style", wx.TAB_TRAVERSAL),
628c7f79
RD
128 self.GetName()
129 )
130
131 # These two things should be done in either case:
132 # Set standard window attributes
133 self.SetupWindow(panel)
134 # Create any child windows of this node
135 self.CreateChildren(panel)
136
137 return panel
138
139
140#----------------------------------------------------------------------
141
142
8fa876ca 143class TestPanel(wx.Panel):
628c7f79
RD
144 def __init__(self, parent, log):
145 self.log = log
8fa876ca 146 wx.Panel.__init__(self, parent, -1)
628c7f79
RD
147
148 # make the components
8fa876ca
RD
149 label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
150 label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
628c7f79 151
8fa876ca
RD
152 text = wx.TextCtrl(self, -1, resourceText,
153 style=wx.TE_READONLY|wx.TE_MULTILINE)
628c7f79
RD
154 text.SetInsertionPoint(0)
155
8fa876ca 156 line = wx.StaticLine(self, -1)
628c7f79
RD
157
158 # Load the resource
8fa876ca 159 res = xrc.EmptyXmlResource()
5cd7ab8d 160 res.InsertHandler(MyCustomPanelXmlHandler())
628c7f79
RD
161 res.LoadFromString(resourceText)
162
163 # Now create a panel from the resource data
5cd7ab8d 164 panel = res.LoadObject(self, "MyPanel", "MyCustomPanel")
628c7f79
RD
165
166 # and do the layout
8fa876ca
RD
167 sizer = wx.BoxSizer(wx.VERTICAL)
168 sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
169 sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
170 sizer.Add(line, 0, wx.EXPAND)
171 sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
628c7f79
RD
172
173 self.SetSizer(sizer)
1e4a197e 174 self.SetAutoLayout(True)
628c7f79
RD
175
176
177#----------------------------------------------------------------------
178
179def runTest(frame, nb, log):
180 win = TestPanel(nb, log)
181 return win
182
183#----------------------------------------------------------------------
184
185
186
187overview = """<html><body>
95bfd958 188<h2><center>wx.XmlResourceHandler</center></h2>
628c7f79 189
95bfd958 190Deriving a class from wx.XmlResourceHandler allows you to specify your
628c7f79
RD
191own classes in XRC resources, and your handler class will then be used
192to create instances of that class when the resource is loaded.
193
194</body></html>
195"""
196
197
198
199if __name__ == '__main__':
200 import sys,os
201 import run
8eca4fef 202 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
628c7f79 203