]>
Commit | Line | Data |
---|---|---|
6158f936 | 1 | <?xml version="1.0" encoding="iso-8859-1" ?> |
d14a1e28 RD |
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> | |
6158f936 | 5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> |
d14a1e28 RD |
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> | |
e8a71fa0 RD |
18 | <div class="section" id="wxname-change"> |
19 | <h1><a name="wxname-change">wxName Change</a></h1> | |
20 | <p>The <strong>wxWindows</strong> project and library is now known as | |
21 | <strong>wxWidgets</strong>. Please see <a class="reference" href="http://lists.wxwidgets.org/cgi-bin/ezmlm-cgi?13:mss:3:200402:eebaopdhchfoagmnideo">here</a> for more details.</p> | |
22 | <p>This won't really affect wxPython all that much, other than the fact | |
23 | that the wxwindows.org domain name will be changing to wxwidgets.org, | |
24 | so mail list, CVS, and etc. addresses will be changing. We're going | |
25 | to try and smooth the transition as much as possible, but I wanted you | |
26 | all to be aware of this change if you run into any issues.</p> | |
27 | </div> | |
d14a1e28 RD |
28 | <div class="section" id="module-initialization"> |
29 | <h1><a name="module-initialization">Module Initialization</a></h1> | |
30 | <p>The import-startup-bootstrap process employed by wxPython was changed | |
31 | such that wxWindows and the underlying gui toolkit are <strong>not</strong> | |
32 | initialized until the wx.App object is created (but before wx.App.OnInit | |
33 | is called.) This was required because of some changes that were made | |
34 | to the C++ wxApp class.</p> | |
35 | <p>There are both benefits and potential problems with this change. The | |
36 | benefits are that you can import wxPython without requiring access to | |
37 | a GUI (for checking version numbers, etc.) and that in a | |
38 | multi-threaded environment the thread that creates the app object will | |
39 | now be the GUI thread instead of the one that imports wxPython. Some | |
40 | potential problems are that the C++ side of the "stock-objects" | |
41 | (wx.BLUE_PEN, wx.TheColourDatabase, etc.) are not initialized until | |
42 | the wx.App object is created, so you should not use them until after | |
6158f936 | 43 | you have created your wx.App object. If you do then an exception will |
e8a71fa0 | 44 | be raised telling you that the C++ object has not been initialized |
6158f936 | 45 | yet.</p> |
d14a1e28 RD |
46 | <p>Also, you will probably not be able to do any kind of GUI or bitmap |
47 | operation unless you first have created an app object, (even on | |
48 | Windows where most anything was possible before.)</p> | |
49 | </div> | |
50 | <div class="section" id="swig-1-3"> | |
51 | <h1><a name="swig-1-3">SWIG 1.3</a></h1> | |
52 | <p>wxPython is now using SWIG 1.3.x from CVS (with several of my own | |
53 | customizations added that I hope to get folded back into the main SWIG | |
54 | distribution.) This has some far reaching ramifications:</p> | |
55 | <blockquote> | |
56 | <p>All classes derive from object and so all are now "new-style | |
57 | classes"</p> | |
58 | <p>Public data members of the C++ classes are wrapped as Python | |
59 | properties using property() instead of using __getattr__/__setattr__ | |
60 | like before. Normally you shouldn't notice any difference, but if | |
61 | you were previously doing something with __getattr__/__setattr__ | |
62 | in derived classes then you may have to adjust things.</p> | |
63 | <p>Static C++ methods are wrapped using the staticmethod() | |
64 | feature of Python and so are accessible as ClassName.MethodName | |
65 | as expected. They are still available as top level functions | |
66 | ClassName_MethodName as before.</p> | |
67 | <p>The relationship between the wxFoo and wxFooPtr classes have | |
68 | changed for the better. Specifically, all instances that you see | |
69 | will be wxFoo even if they are created internally using wxFooPtr, | |
70 | because wxFooPtr.__init__ will change the instance's __class__ as | |
71 | part of the initialization. If you have any code that checks | |
72 | class type using something like isinstance(obj, wxFooPtr) you will | |
73 | need to change it to isinstance(obj, wxFoo).</p> | |
74 | </blockquote> | |
75 | </div> | |
76 | <div class="section" id="binding-events"> | |
77 | <h1><a name="binding-events">Binding Events</a></h1> | |
78 | <p>All of the EVT_* functions are now instances of the wx.PyEventBinder | |
79 | class. They have a __call__ method so they can still be used as | |
80 | functions like before, but making them instances adds some | |
81 | flexibility.</p> | |
82 | <p>wx.EvtHandler (the base class for wx.Window) now has a Bind method that | |
83 | makes binding events to windows a little easier. Here is its | |
84 | definition and docstring:</p> | |
85 | <pre class="literal-block"> | |
86 | def Bind(self, event, handler, source=None, id=wxID_ANY, id2=wxID_ANY): | |
87 | """ | |
88 | Bind an event to an event handler. | |
89 | ||
90 | event One of the EVT_* objects that specifies the | |
91 | type of event to bind. | |
92 | ||
93 | handler A callable object to be invoked when the event | |
94 | is delivered to self. Pass None to disconnect an | |
95 | event handler. | |
96 | ||
97 | source Sometimes the event originates from a different window | |
98 | than self, but you still want to catch it in self. (For | |
99 | example, a button event delivered to a frame.) By | |
100 | passing the source of the event, the event handling | |
101 | system is able to differentiate between the same event | |
102 | type from different controls. | |
103 | ||
104 | id,id2 Used for menu IDs or for event types that require a | |
105 | range of IDs | |
106 | ||
107 | """ | |
108 | </pre> | |
109 | <p>Some examples of its use:</p> | |
110 | <pre class="literal-block"> | |
111 | self.Bind(wx.EVT_SIZE, self.OnSize) | |
112 | self.Bind(wx.EVT_BUTTON, self.OnButtonClick, theButton) | |
8eda5e35 RD |
113 | self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT) |
114 | </pre> | |
115 | <p>The wx.Menu methods that add items to a wx.Menu have been modified | |
116 | such that they return a reference to the wx.MenuItem that was created. | |
117 | Additionally menu items and toolbar items have been modified to | |
118 | automatically generate a new ID if -1 is given, similar to using -1 | |
119 | with window classess. This means that you can create menu or toolbar | |
120 | items and event bindings without having to predefine a unique menu ID, | |
121 | although you still can use IDs just like before if you want. For | |
e8a71fa0 RD |
122 | example, these are all equivallent other than their specific ID |
123 | values:</p> | |
8eda5e35 RD |
124 | <pre class="literal-block"> |
125 | 1. | |
126 | item = menu.Append(-1, "E&xit", "Terminate the App") | |
127 | self.Bind(wx.EVT_MENU, self.OnExit, item) | |
128 | ||
129 | 2. | |
130 | item = menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App") | |
131 | self.Bind(wx.EVT_MENU, self.OnExit, item) | |
132 | ||
133 | 3. | |
134 | menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App") | |
135 | self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT) | |
d14a1e28 | 136 | </pre> |
d14a1e28 RD |
137 | <p>If you create your own custom event types and EVT_* functions, and you |
138 | want to be able to use them with the Bind method above then you should | |
139 | change your EVT_* to be an instance of wxPyEventBinder instead of a | |
140 | function. If you used to have something like this:</p> | |
141 | <pre class="literal-block"> | |
142 | myCustomEventType = wxNewEventType() | |
143 | def EVT_MY_CUSTOM_EVENT(win, id, func): | |
144 | win.Connect(id, -1, myCustomEventType, func) | |
145 | </pre> | |
146 | <p>Change it like so:</p> | |
147 | <pre class="literal-block"> | |
6158f936 RD |
148 | myCustomEventType = wx.NewEventType() |
149 | EVT_MY_CUSTOM_EVENT = wx.PyEventBinder(myCustomEventType, 1) | |
d14a1e28 RD |
150 | </pre> |
151 | <p>The second parameter is an integer in [0, 1, 2] that specifies the | |
152 | number of IDs that are needed to be passed to Connect.</p> | |
153 | </div> | |
154 | <div class="section" id="the-wx-namespace"> | |
155 | <h1><a name="the-wx-namespace">The wx Namespace</a></h1> | |
156 | <p>The second phase of the wx Namespace Transition has begun. That means | |
157 | that the real names of the classes and other symbols do not have the | |
158 | 'wx' prefix and the modules are located in a Python package named | |
159 | wx. There is still a Python package named wxPython with modules | |
160 | that have the names with the wx prefix for backwards compatibility. | |
161 | Instead of dynamically changing the names at module load time like in | |
162 | 2.4, the compatibility modules are generated at build time and contain | |
163 | assignment statements like this:</p> | |
164 | <pre class="literal-block"> | |
165 | wxWindow = wx.core.Window | |
166 | </pre> | |
167 | <p>Don't let the "core" in the name bother you. That and some other | |
168 | modules are implementation details, and everything that was in the | |
6158f936 RD |
169 | wxPython.wx module before will still be in the wx package namespace |
170 | after this change. So from your code you would use it as wx.Window.</p> | |
d14a1e28 RD |
171 | <p>A few notes about how all of this was accomplished might be |
172 | interesting... SWIG is now run twice for each module that it is | |
173 | generating code for. The first time it outputs an XML representaion | |
174 | of the parse tree, which can be up to 20MB and 300K lines in size! | |
175 | That XML is then run through a little Python script that creates a | |
176 | file full of SWIG %rename directives that take the wx off of the | |
177 | names, and also generates the Python compatibility file described | |
178 | above that puts the wx back on the names. SWIG is then run a second | |
179 | time to generate the C++ code to implement the extension module, and | |
180 | uses the %rename directives that were generated in the first step.</p> | |
181 | <p>Not every name is handled correctly (but the bulk of them are) and so | |
182 | some work has to be done by hand, especially for the reverse-renamers. | |
183 | So expect a few flaws here and there until everything gets sorted out.</p> | |
6158f936 RD |
184 | <p>In summary, the wx package and names without the "wx" prefix are now |
185 | the official form of the wxPython classes. For example:</p> | |
186 | <pre class="literal-block"> | |
187 | import wx | |
188 | ||
189 | class MyFrame(wx.Frame): | |
190 | def __init__(self, parent, title): | |
191 | wx.Frame.__init__(self, parent, -1, title) | |
192 | p = wx.Panel(self, -1) | |
193 | b = wx.Button(p, -1, "Do It", (10,10)) | |
194 | self.Bind(wx.EVT_BUTTON, self.JustDoIt, b) | |
195 | ||
196 | def JustDoIt(self, evt): | |
197 | print "It's done!" | |
198 | ||
199 | app = wx.PySimpleApp() | |
200 | f = MyFrame(None, "What's up?") | |
201 | f.Show() | |
202 | app.MainLoop() | |
203 | </pre> | |
204 | <p>You shouldn't need to migrate all your modules over to use the new | |
205 | package and names right away as there are modules in place that try to | |
206 | provide as much backwards compatibility of the names as possible. If | |
82a074ce | 207 | you rewrote the above sample using "from wxPython.wx import * ", the |
6158f936 RD |
208 | old wxNames, and the old style of event binding it will still work |
209 | just fine.</p> | |
d14a1e28 RD |
210 | </div> |
211 | <div class="section" id="new-wx-dc-methods"> | |
212 | <h1><a name="new-wx-dc-methods">New wx.DC Methods</a></h1> | |
213 | <p>Many of the Draw methods of wx.DC have alternate forms in C++ that take | |
214 | wxPoint or wxSize parameters (let's call these <em>Type A</em>) instead of | |
215 | the individual x, y, width, height, etc. parameters (and we'll call | |
216 | these <em>Type B</em>). In the rest of the library I normally made the <em>Type | |
217 | A</em> forms of the methods be the default method with the "normal" name, | |
218 | and had renamed the <em>Type B</em> forms of the methods to some similar | |
219 | name. For example in wx.Window we have these Python methods:</p> | |
220 | <pre class="literal-block"> | |
221 | SetSize(size) # Type A | |
222 | SetSizeWH(width, height) # Type B | |
223 | </pre> | |
224 | <p>For various reasons the new <em>Type A</em> methods in wx.DC were never added | |
6158f936 RD |
225 | and the existing <em>Type B</em> methods were never renamed. Now that lots |
226 | of other things are also changing in wxPython it has been decided that | |
227 | it is a good time to also do the method renaming in wx.DC too in order | |
d14a1e28 RD |
228 | to be consistent with the rest of the library. The methods in wx.DC |
229 | that are affected are listed here:</p> | |
230 | <pre class="literal-block"> | |
231 | FloodFillXY(x, y, colour, style = wx.FLOOD_SURFACE) | |
232 | FloodFill(point, colour, style = wx.FLOOD_SURFACE) | |
233 | ||
234 | GetPixelXY(x, y) | |
235 | GetPixel(point) | |
236 | ||
237 | DrawLineXY(x1, y1, x2, y2) | |
238 | DrawLine(point1, point2) | |
239 | ||
240 | CrossHairXY(x, y) | |
241 | CrossHair(point) | |
242 | ||
243 | DrawArcXY(x1, y1, x2, y2, xc, yc) | |
244 | DrawArc(point1, point2, center) | |
245 | ||
246 | DrawCheckMarkXY(x, y, width, height) | |
247 | DrawCheckMark(rect) | |
248 | ||
249 | DrawEllipticArcXY(x, y, w, h, start_angle, end_angle) | |
250 | DrawEllipticArc(point, size, start_angle, end_angle) | |
251 | ||
252 | DrawPointXY(x, y) | |
253 | DrawPoint(point) | |
254 | ||
255 | DrawRectangleXY(x, y, width, height) | |
256 | DrawRectangle(point, size) | |
257 | DrawRectangleRect(rect) | |
258 | ||
259 | DrawRoundedRectangleXY(x, y, width, height, radius) | |
260 | DrawRoundedRectangle(point, size, radius) | |
261 | DrawRoundedRectangleRect(rect, radius) | |
262 | ||
263 | DrawCircleXY(x, y, radius) | |
264 | DrawCircle(point, radius) | |
265 | ||
266 | DrawEllipseXY(x, y, width, height) | |
267 | DrawEllipse(point, size) | |
268 | DrawEllipseRect(rect) | |
269 | ||
270 | DrawIconXY(icon, x, y) | |
271 | DrawIcon(icon, point) | |
272 | ||
273 | DrawBitmapXY(bmp, x, y, useMask = FALSE) | |
274 | DrawBitmap(bmp, point, useMask = FALSE) | |
275 | ||
276 | DrawTextXY(text, x, y) | |
277 | DrawText(text, point) | |
278 | ||
279 | DrawRotatedTextXY(text, x, y, angle) | |
280 | DrawRotatedText(text, point, angle) | |
281 | ||
282 | ||
283 | BlitXY(xdest, ydest, width, height, sourceDC, xsrc, ysrc, | |
284 | rop = wxCOPY, useMask = FALSE, xsrcMask = -1, ysrcMask = -1) | |
285 | Blit(destPt, size, sourceDC, srcPt, | |
286 | rop = wxCOPY, useMask = FALSE, srcPtMask = wx.DefaultPosition) | |
6158f936 | 287 | |
82a074ce | 288 | SetClippingRegionXY(x, y, width, height) |
6158f936 RD |
289 | SetClippingRegion(point, size) |
290 | SetClippingRect(rect) | |
291 | SetClippingRegionAsRegion(region); | |
d14a1e28 | 292 | </pre> |
e75fd8a4 RD |
293 | <p>If you have code that draws on a DC and you are using the new wx |
294 | namespace then you <strong>will</strong> get errors because of these changes, but | |
295 | it should be easy to fix the code. You can either change the name of | |
296 | the <em>Type B</em> method called to the names shown above, or just add | |
297 | parentheses around the parameters as needed to turn them into tuples | |
298 | and let the SWIG typemaps turn them into the wx.Point or wx.Size | |
299 | object that is expected. Then you will be calling the new <em>Type A</em> | |
300 | method. For example, if you had this code before:</p> | |
d14a1e28 RD |
301 | <pre class="literal-block"> |
302 | dc.DrawRectangle(x, y, width, height) | |
303 | </pre> | |
6158f936 RD |
304 | <p>You could either continue to use the <em>Type B</em> method bu changing the |
305 | name to DrawRectabgleXY, or just change it to the new <em>Type A</em> by | |
306 | adding some parentheses like this:</p> | |
d14a1e28 RD |
307 | <pre class="literal-block"> |
308 | dc.DrawRectangle((x, y), (width, height)) | |
309 | </pre> | |
310 | <p>Or if you were already using a point and size:</p> | |
311 | <pre class="literal-block"> | |
312 | dc.DrawRectangle(p.x, p.y, s.width, s.height) | |
313 | </pre> | |
6158f936 | 314 | <p>Then you can just simplify it like this:</p> |
d14a1e28 RD |
315 | <pre class="literal-block"> |
316 | dc.DrawRectangle(p, s) | |
317 | </pre> | |
e75fd8a4 RD |
318 | <p>Now before you start yelling and screaming at me for breaking all your |
319 | code, take note that I said above "...using the new wx namespace..." | |
320 | That's because if you are still importing from wxPython.wx then there | |
321 | are some classes defined there with Draw and etc. methods that have | |
322 | 2.4 compatible signatures. However if/when the old wxPython.wx | |
323 | namespace is removed then these classes will be removed too so you | |
324 | should plan on migrating to the new namespace and new DC Draw methods | |
325 | before that time.</p> | |
d14a1e28 RD |
326 | </div> |
327 | <div class="section" id="building-extending-and-embedding-wxpython"> | |
328 | <h1><a name="building-extending-and-embedding-wxpython">Building, Extending and Embedding wxPython</a></h1> | |
329 | <p>wxPython's setup.py script now expects to use existing libraries for | |
330 | the contribs (gizmos, stc, xrc, etc.) rather than building local | |
331 | copies of them. If you build your own copies of wxPython please be | |
332 | aware that you now need to also build the ogl, stc, xrc, and gizmos | |
333 | libraries in addition to the main wx lib. [[TODO: update the | |
334 | BUILD.*.txt files too!]]</p> | |
335 | <p>The wxPython.h and other header files are now in | |
336 | .../wxPython/include/wx/wxPython instead of in wxPython/src. You should | |
337 | include it via the "wx/wxPython/wxPython.h" path and add | |
338 | .../wxPython/include to your list of include paths. [[TODO: Install | |
339 | these headers on Linux...]]</p> | |
340 | <p>You no longer need to call wxClassInfo::CleanUpClasses() and | |
341 | wxClassInfo::InitializeClasses() in your extensions or when embedding | |
342 | wxPython.</p> | |
343 | </div> | |
6158f936 RD |
344 | <div class="section" id="two-or-three-phase-create"> |
345 | <h1><a name="two-or-three-phase-create">Two (or Three!) Phase Create</a></h1> | |
346 | <p>If you use the Precreate/Create method of instantiating a window, (for | |
347 | example, to set an extended style flag, or for XRC handlers) then | |
348 | there is now a new method named PostCreate to help with transplanting | |
349 | the brain of the prewindow instance into the derived window instance. | |
350 | For example:</p> | |
351 | <pre class="literal-block"> | |
352 | class MyDialog(wx.Dialog): | |
353 | def __init__(self, parent, ID, title, pos, size, style): | |
354 | pre = wx.PreDialog() | |
355 | pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) | |
356 | pre.Create(parent, ID, title, pos, size, style) | |
357 | self.PostCreate(pre) | |
358 | </pre> | |
359 | </div> | |
360 | <div class="section" id="sizers"> | |
361 | <h1><a name="sizers">Sizers</a></h1> | |
8eda5e35 RD |
362 | <p>The hack allowing the old "option" keyword parameter has been removed. |
363 | If you use keyworkd args with wxSizer Add, Insert, or Prepend methods | |
364 | then you will need to use the "proportion" name instead of "option".</p> | |
6158f936 RD |
365 | <p>When adding a spacer to a sizer you now need to use a wxSize or a |
366 | 2-integer sequence instead of separate width and height parameters.</p> | |
367 | <p>The wxGridBagSizer class (very similar to the RowColSizer in the | |
368 | library) has been added to C++ and wrapped for wxPython. It can also | |
369 | be used from XRC.</p> | |
370 | <p>You should not use AddWindow, AddSizer, AddSpacer (and similar for | |
371 | Insert, Prepend, and etc.) methods any longer. Just use Add and the | |
372 | wrappers will figure out what to do.</p> | |
373 | </div> | |
d14a1e28 RD |
374 | <div class="section" id="other-stuff"> |
375 | <h1><a name="other-stuff">Other Stuff</a></h1> | |
376 | <p>Instead of over a dozen separate extension modules linked together | |
377 | into a single extension module, the "core" module is now just a few | |
378 | extensions that are linked independently, and then merged together | |
379 | later into the main namespace via Python code.</p> | |
8eda5e35 RD |
380 | <p>Because of the above and also because of the way the new SWIG works, |
381 | the "internal" module names have changed, but you shouldn't have been | |
382 | using them anyway so it shouldn't bother you. ;-)</p> | |
383 | <p>The help module no longer exists and the classes therein are now part | |
384 | of the core module imported with wxPython.wx or the wx package.</p> | |
6158f936 RD |
385 | <p>wxPyDefaultPosition and wxPyDefaultSize are gone. Use the |
386 | wxDefaultPosition and wxDefaultSize objects instead.</p> | |
387 | <p>Similarly, the wxSystemSettings backwards compatibiility aliases for | |
388 | GetSystemColour, GetSystemFont and GetSystemMetric have also gone into | |
389 | the bit-bucket. Use GetColour, GetFont and GetMetric instead.</p> | |
390 | <p>The wx.NO_FULL_REPAINT_ON_RESIZE style is now the default style for | |
391 | all windows. The name still exists for compatibility, but it is set | |
392 | to zero. If you want to disable the setting (so it matches the old | |
393 | default) then you need to use the new wx.FULL_REPAINT_ON_RESIZE style | |
394 | flag otherwise only the freshly exposed areas of the window will be | |
395 | refreshed.</p> | |
396 | <p>wxPyTypeCast has been removed. Since we've had the OOR (Original | |
397 | Object Return) for a couple years now there should be no need to use | |
398 | wxPyTypeCast at all.</p> | |
8eda5e35 RD |
399 | <p>If you use the old wxPython package and wxPython.wx namespace then |
400 | there are compatibility aliases for much of the above items.</p> | |
401 | <p>The wxWave class has been renamed to wxSound, and now has a slightly | |
402 | different API.</p> | |
6158f936 | 403 | </div> |
d14a1e28 | 404 | </div> |
6158f936 RD |
405 | <hr class="footer" /> |
406 | <div class="footer"> | |
e8a71fa0 | 407 | Generated on: 2004-02-27 23:30 UTC. |
d14a1e28 RD |
408 | </div> |
409 | </body> | |
410 | </html> |