]> git.saurik.com Git - wxWidgets.git/blob - wxPython/docs/MigrationGuide.html
reSWIGged
[wxWidgets.git] / wxPython / docs / MigrationGuide.html
1 <?xml version="1.0" encoding="utf-8" ?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
7 <title>wxPython 2.5 Migration Guide</title>
8 <link rel="stylesheet" href="default.css" type="text/css" />
9 </head>
10 <body>
11 <div class="document" id="wxpython-2-5-migration-guide">
12 <h1 class="title">wxPython 2.5 Migration Guide</h1>
13 <p>This document will help explain some of the major changes in wxPython
14 2.5 and let you know what you need to do to adapt your programs to
15 those changes. Be sure to also check in the CHANGES.txt file like
16 usual to see info about the not so major changes and other things that
17 have been added to wxPython.</p>
18 <div class="section" id="module-initialization">
19 <h1><a name="module-initialization">Module Initialization</a></h1>
20 <p>The import-startup-bootstrap process employed by wxPython was changed
21 such that wxWindows and the underlying gui toolkit are <strong>not</strong>
22 initialized until the wx.App object is created (but before wx.App.OnInit
23 is called.) This was required because of some changes that were made
24 to the C++ wxApp class.</p>
25 <p>There are both benefits and potential problems with this change. The
26 benefits are that you can import wxPython without requiring access to
27 a GUI (for checking version numbers, etc.) and that in a
28 multi-threaded environment the thread that creates the app object will
29 now be the GUI thread instead of the one that imports wxPython. Some
30 potential problems are that the C++ side of the &quot;stock-objects&quot;
31 (wx.BLUE_PEN, wx.TheColourDatabase, etc.) are not initialized until
32 the wx.App object is created, so you should not use them until after
33 you have created your wx.App object. (In fact, until I find a better
34 solution trying to use one of the stock objects before the app is
35 created will probably result in a crash.)</p>
36 <p>Also, you will probably not be able to do any kind of GUI or bitmap
37 operation unless you first have created an app object, (even on
38 Windows where most anything was possible before.)</p>
39 </div>
40 <div class="section" id="swig-1-3">
41 <h1><a name="swig-1-3">SWIG 1.3</a></h1>
42 <p>wxPython is now using SWIG 1.3.x from CVS (with several of my own
43 customizations added that I hope to get folded back into the main SWIG
44 distribution.) This has some far reaching ramifications:</p>
45 <blockquote>
46 <p>All classes derive from object and so all are now &quot;new-style
47 classes&quot;</p>
48 <p>Public data members of the C++ classes are wrapped as Python
49 properties using property() instead of using __getattr__/__setattr__
50 like before. Normally you shouldn't notice any difference, but if
51 you were previously doing something with __getattr__/__setattr__
52 in derived classes then you may have to adjust things.</p>
53 <p>Static C++ methods are wrapped using the staticmethod()
54 feature of Python and so are accessible as ClassName.MethodName
55 as expected. They are still available as top level functions
56 ClassName_MethodName as before.</p>
57 <p>The relationship between the wxFoo and wxFooPtr classes have
58 changed for the better. Specifically, all instances that you see
59 will be wxFoo even if they are created internally using wxFooPtr,
60 because wxFooPtr.__init__ will change the instance's __class__ as
61 part of the initialization. If you have any code that checks
62 class type using something like isinstance(obj, wxFooPtr) you will
63 need to change it to isinstance(obj, wxFoo).</p>
64 </blockquote>
65 </div>
66 <div class="section" id="binding-events">
67 <h1><a name="binding-events">Binding Events</a></h1>
68 <p>All of the EVT_* functions are now instances of the wx.PyEventBinder
69 class. They have a __call__ method so they can still be used as
70 functions like before, but making them instances adds some
71 flexibility.</p>
72 <p>wx.EvtHandler (the base class for wx.Window) now has a Bind method that
73 makes binding events to windows a little easier. Here is its
74 definition and docstring:</p>
75 <pre class="literal-block">
76 def Bind(self, event, handler, source=None, id=wxID_ANY, id2=wxID_ANY):
77 &quot;&quot;&quot;
78 Bind an event to an event handler.
79
80 event One of the EVT_* objects that specifies the
81 type of event to bind.
82
83 handler A callable object to be invoked when the event
84 is delivered to self. Pass None to disconnect an
85 event handler.
86
87 source Sometimes the event originates from a different window
88 than self, but you still want to catch it in self. (For
89 example, a button event delivered to a frame.) By
90 passing the source of the event, the event handling
91 system is able to differentiate between the same event
92 type from different controls.
93
94 id,id2 Used for menu IDs or for event types that require a
95 range of IDs
96
97 &quot;&quot;&quot;
98 </pre>
99 <p>Some examples of its use:</p>
100 <pre class="literal-block">
101 self.Bind(wx.EVT_SIZE, self.OnSize)
102 self.Bind(wx.EVT_BUTTON, self.OnButtonClick, theButton)
103 self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT)
104 </pre>
105 <p>I hope to be able to remove the need for using IDs even for menu
106 events too...</p>
107 <p>If you create your own custom event types and EVT_* functions, and you
108 want to be able to use them with the Bind method above then you should
109 change your EVT_* to be an instance of wxPyEventBinder instead of a
110 function. If you used to have something like this:</p>
111 <pre class="literal-block">
112 myCustomEventType = wxNewEventType()
113 def EVT_MY_CUSTOM_EVENT(win, id, func):
114 win.Connect(id, -1, myCustomEventType, func)
115 </pre>
116 <p>Change it like so:</p>
117 <pre class="literal-block">
118 myCustomEventType = wxNewEventType()
119 EVT_MY_CUSTOM_EVENT = wxPyEventBinder(myCustomEventType, 1)
120 </pre>
121 <p>The second parameter is an integer in [0, 1, 2] that specifies the
122 number of IDs that are needed to be passed to Connect.</p>
123 </div>
124 <div class="section" id="the-wx-namespace">
125 <h1><a name="the-wx-namespace">The wx Namespace</a></h1>
126 <p>The second phase of the wx Namespace Transition has begun. That means
127 that the real names of the classes and other symbols do not have the
128 'wx' prefix and the modules are located in a Python package named
129 wx. There is still a Python package named wxPython with modules
130 that have the names with the wx prefix for backwards compatibility.
131 Instead of dynamically changing the names at module load time like in
132 2.4, the compatibility modules are generated at build time and contain
133 assignment statements like this:</p>
134 <pre class="literal-block">
135 wxWindow = wx.core.Window
136 </pre>
137 <p>Don't let the &quot;core&quot; in the name bother you. That and some other
138 modules are implementation details, and everything that was in the
139 wxPython.wx before will still be in the wx package namespace after
140 this change. So from your code you would use it as wx.Window.</p>
141 <p>A few notes about how all of this was accomplished might be
142 interesting... SWIG is now run twice for each module that it is
143 generating code for. The first time it outputs an XML representaion
144 of the parse tree, which can be up to 20MB and 300K lines in size!
145 That XML is then run through a little Python script that creates a
146 file full of SWIG %rename directives that take the wx off of the
147 names, and also generates the Python compatibility file described
148 above that puts the wx back on the names. SWIG is then run a second
149 time to generate the C++ code to implement the extension module, and
150 uses the %rename directives that were generated in the first step.</p>
151 <p>Not every name is handled correctly (but the bulk of them are) and so
152 some work has to be done by hand, especially for the reverse-renamers.
153 So expect a few flaws here and there until everything gets sorted out.</p>
154 </div>
155 <div class="section" id="new-wx-dc-methods">
156 <h1><a name="new-wx-dc-methods">New wx.DC Methods</a></h1>
157 <p>Many of the Draw methods of wx.DC have alternate forms in C++ that take
158 wxPoint or wxSize parameters (let's call these <em>Type A</em>) instead of
159 the individual x, y, width, height, etc. parameters (and we'll call
160 these <em>Type B</em>). In the rest of the library I normally made the <em>Type
161 A</em> forms of the methods be the default method with the &quot;normal&quot; name,
162 and had renamed the <em>Type B</em> forms of the methods to some similar
163 name. For example in wx.Window we have these Python methods:</p>
164 <pre class="literal-block">
165 SetSize(size) # Type A
166 SetSizeWH(width, height) # Type B
167 </pre>
168 <p>For various reasons the new <em>Type A</em> methods in wx.DC were never added
169 and the existing <em>Type B</em> methods renamed. Now that lots of other
170 things are also changing in wxPython that it has been decided that it
171 is a good time to also do the method renaming in wx.DC too, in order
172 to be consistent with the rest of the library. The methods in wx.DC
173 that are affected are listed here:</p>
174 <pre class="literal-block">
175 FloodFillXY(x, y, colour, style = wx.FLOOD_SURFACE)
176 FloodFill(point, colour, style = wx.FLOOD_SURFACE)
177
178 GetPixelXY(x, y)
179 GetPixel(point)
180
181 DrawLineXY(x1, y1, x2, y2)
182 DrawLine(point1, point2)
183
184 CrossHairXY(x, y)
185 CrossHair(point)
186
187 DrawArcXY(x1, y1, x2, y2, xc, yc)
188 DrawArc(point1, point2, center)
189
190 DrawCheckMarkXY(x, y, width, height)
191 DrawCheckMark(rect)
192
193 DrawEllipticArcXY(x, y, w, h, start_angle, end_angle)
194 DrawEllipticArc(point, size, start_angle, end_angle)
195
196 DrawPointXY(x, y)
197 DrawPoint(point)
198
199 DrawRectangleXY(x, y, width, height)
200 DrawRectangle(point, size)
201 DrawRectangleRect(rect)
202
203 DrawRoundedRectangleXY(x, y, width, height, radius)
204 DrawRoundedRectangle(point, size, radius)
205 DrawRoundedRectangleRect(rect, radius)
206
207 DrawCircleXY(x, y, radius)
208 DrawCircle(point, radius)
209
210 DrawEllipseXY(x, y, width, height)
211 DrawEllipse(point, size)
212 DrawEllipseRect(rect)
213
214 DrawIconXY(icon, x, y)
215 DrawIcon(icon, point)
216
217 DrawBitmapXY(bmp, x, y, useMask = FALSE)
218 DrawBitmap(bmp, point, useMask = FALSE)
219
220 DrawTextXY(text, x, y)
221 DrawText(text, point)
222
223 DrawRotatedTextXY(text, x, y, angle)
224 DrawRotatedText(text, point, angle)
225
226
227 BlitXY(xdest, ydest, width, height, sourceDC, xsrc, ysrc,
228 rop = wxCOPY, useMask = FALSE, xsrcMask = -1, ysrcMask = -1)
229 Blit(destPt, size, sourceDC, srcPt,
230 rop = wxCOPY, useMask = FALSE, srcPtMask = wx.DefaultPosition)
231 </pre>
232 <p>If you have code that draws on a DC you <strong>will</strong> get errors because of
233 these changes, but it should be easy to fix the code. You can either
234 change the name of the <em>Type B</em> method called as shown above, or just
235 add parentheses around the parameters as needed to turn them into
236 tuples and let the SWIG typemaps turn them into the wx.Point or
237 wx.Size object that is expected. For example, if you had this code
238 before:</p>
239 <pre class="literal-block">
240 dc.DrawRectangle(x, y, width, height)
241 </pre>
242 <p>You could just change it like this:</p>
243 <pre class="literal-block">
244 dc.DrawRectangle((x, y), (width, height))
245 </pre>
246 <p>Or if you were already using a point and size:</p>
247 <pre class="literal-block">
248 dc.DrawRectangle(p.x, p.y, s.width, s.height)
249 </pre>
250 <p>Then you can just change it like this:</p>
251 <pre class="literal-block">
252 dc.DrawRectangle(p, s)
253 </pre>
254 </div>
255 <div class="section" id="building-extending-and-embedding-wxpython">
256 <h1><a name="building-extending-and-embedding-wxpython">Building, Extending and Embedding wxPython</a></h1>
257 <p>wxPython's setup.py script now expects to use existing libraries for
258 the contribs (gizmos, stc, xrc, etc.) rather than building local
259 copies of them. If you build your own copies of wxPython please be
260 aware that you now need to also build the ogl, stc, xrc, and gizmos
261 libraries in addition to the main wx lib. [[TODO: update the
262 BUILD.*.txt files too!]]</p>
263 <p>The wxPython.h and other header files are now in
264 .../wxPython/include/wx/wxPython instead of in wxPython/src. You should
265 include it via the &quot;wx/wxPython/wxPython.h&quot; path and add
266 .../wxPython/include to your list of include paths. [[TODO: Install
267 these headers on Linux...]]</p>
268 <p>You no longer need to call wxClassInfo::CleanUpClasses() and
269 wxClassInfo::InitializeClasses() in your extensions or when embedding
270 wxPython.</p>
271 </div>
272 <div class="section" id="other-stuff">
273 <h1><a name="other-stuff">Other Stuff</a></h1>
274 <p>Instead of over a dozen separate extension modules linked together
275 into a single extension module, the &quot;core&quot; module is now just a few
276 extensions that are linked independently, and then merged together
277 later into the main namespace via Python code.</p>
278 <p>Because of the above, the &quot;internal&quot; module names have changed, but
279 you shouldn't have been using them anyway so it shouldn't bother
280 you. ;-)</p>
281 </div>
282 </div>
283 </body>
284 </html>