]>
Commit | Line | Data |
---|---|---|
1 | <?xml version="1.0" encoding="iso-8859-1" ?> | |
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=iso-8859-1" /> | |
6 | <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" /> | |
7 | <title>wxPython 2.6 Migration Guide</title> | |
8 | <style type="text/css"> | |
9 | ||
10 | /* | |
11 | :Author: David Goodger | |
12 | :Contact: goodger@users.sourceforge.net | |
13 | :Date: $Date$ | |
14 | :Revision: $Revision$ | |
15 | :Copyright: This stylesheet has been placed in the public domain. | |
16 | ||
17 | Default cascading style sheet for the HTML output of Docutils. | |
18 | ||
19 | See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to | |
20 | customize this style sheet. | |
21 | */ | |
22 | ||
23 | /* used to remove borders from tables and images */ | |
24 | .borderless, table.borderless td, table.borderless th { | |
25 | border: 0 } | |
26 | ||
27 | table.borderless td, table.borderless th { | |
28 | /* Override padding for "table.docutils td" with "! important". | |
29 | The right padding separates the table cells. */ | |
30 | padding: 0 0.5em 0 0 ! important } | |
31 | ||
32 | .first { | |
33 | /* Override more specific margin styles with "! important". */ | |
34 | margin-top: 0 ! important } | |
35 | ||
36 | .last, .with-subtitle { | |
37 | margin-bottom: 0 ! important } | |
38 | ||
39 | .hidden { | |
40 | display: none } | |
41 | ||
42 | a.toc-backref { | |
43 | text-decoration: none ; | |
44 | color: black } | |
45 | ||
46 | blockquote.epigraph { | |
47 | margin: 2em 5em ; } | |
48 | ||
49 | dl.docutils dd { | |
50 | margin-bottom: 0.5em } | |
51 | ||
52 | /* Uncomment (and remove this text!) to get bold-faced definition list terms | |
53 | dl.docutils dt { | |
54 | font-weight: bold } | |
55 | */ | |
56 | ||
57 | div.abstract { | |
58 | margin: 2em 5em } | |
59 | ||
60 | div.abstract p.topic-title { | |
61 | font-weight: bold ; | |
62 | text-align: center } | |
63 | ||
64 | div.admonition, div.attention, div.caution, div.danger, div.error, | |
65 | div.hint, div.important, div.note, div.tip, div.warning { | |
66 | margin: 2em ; | |
67 | border: medium outset ; | |
68 | padding: 1em } | |
69 | ||
70 | div.admonition p.admonition-title, div.hint p.admonition-title, | |
71 | div.important p.admonition-title, div.note p.admonition-title, | |
72 | div.tip p.admonition-title { | |
73 | font-weight: bold ; | |
74 | font-family: sans-serif } | |
75 | ||
76 | div.attention p.admonition-title, div.caution p.admonition-title, | |
77 | div.danger p.admonition-title, div.error p.admonition-title, | |
78 | div.warning p.admonition-title { | |
79 | color: red ; | |
80 | font-weight: bold ; | |
81 | font-family: sans-serif } | |
82 | ||
83 | /* Uncomment (and remove this text!) to get reduced vertical space in | |
84 | compound paragraphs. | |
85 | div.compound .compound-first, div.compound .compound-middle { | |
86 | margin-bottom: 0.5em } | |
87 | ||
88 | div.compound .compound-last, div.compound .compound-middle { | |
89 | margin-top: 0.5em } | |
90 | */ | |
91 | ||
92 | div.dedication { | |
93 | margin: 2em 5em ; | |
94 | text-align: center ; | |
95 | font-style: italic } | |
96 | ||
97 | div.dedication p.topic-title { | |
98 | font-weight: bold ; | |
99 | font-style: normal } | |
100 | ||
101 | div.figure { | |
102 | margin-left: 2em ; | |
103 | margin-right: 2em } | |
104 | ||
105 | div.footer, div.header { | |
106 | clear: both; | |
107 | font-size: smaller } | |
108 | ||
109 | div.line-block { | |
110 | display: block ; | |
111 | margin-top: 1em ; | |
112 | margin-bottom: 1em } | |
113 | ||
114 | div.line-block div.line-block { | |
115 | margin-top: 0 ; | |
116 | margin-bottom: 0 ; | |
117 | margin-left: 1.5em } | |
118 | ||
119 | div.sidebar { | |
120 | margin-left: 1em ; | |
121 | border: medium outset ; | |
122 | padding: 1em ; | |
123 | background-color: #ffffee ; | |
124 | width: 40% ; | |
125 | float: right ; | |
126 | clear: right } | |
127 | ||
128 | div.sidebar p.rubric { | |
129 | font-family: sans-serif ; | |
130 | font-size: medium } | |
131 | ||
132 | div.system-messages { | |
133 | margin: 5em } | |
134 | ||
135 | div.system-messages h1 { | |
136 | color: red } | |
137 | ||
138 | div.system-message { | |
139 | border: medium outset ; | |
140 | padding: 1em } | |
141 | ||
142 | div.system-message p.system-message-title { | |
143 | color: red ; | |
144 | font-weight: bold } | |
145 | ||
146 | div.topic { | |
147 | margin: 2em } | |
148 | ||
149 | h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, | |
150 | h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { | |
151 | margin-top: 0.4em } | |
152 | ||
153 | h1.title { | |
154 | text-align: center } | |
155 | ||
156 | h2.subtitle { | |
157 | text-align: center } | |
158 | ||
159 | hr.docutils { | |
160 | width: 75% } | |
161 | ||
162 | img.align-left { | |
163 | clear: left } | |
164 | ||
165 | img.align-right { | |
166 | clear: right } | |
167 | ||
168 | ol.simple, ul.simple { | |
169 | margin-bottom: 1em } | |
170 | ||
171 | ol.arabic { | |
172 | list-style: decimal } | |
173 | ||
174 | ol.loweralpha { | |
175 | list-style: lower-alpha } | |
176 | ||
177 | ol.upperalpha { | |
178 | list-style: upper-alpha } | |
179 | ||
180 | ol.lowerroman { | |
181 | list-style: lower-roman } | |
182 | ||
183 | ol.upperroman { | |
184 | list-style: upper-roman } | |
185 | ||
186 | p.attribution { | |
187 | text-align: right ; | |
188 | margin-left: 50% } | |
189 | ||
190 | p.caption { | |
191 | font-style: italic } | |
192 | ||
193 | p.credits { | |
194 | font-style: italic ; | |
195 | font-size: smaller } | |
196 | ||
197 | p.label { | |
198 | white-space: nowrap } | |
199 | ||
200 | p.rubric { | |
201 | font-weight: bold ; | |
202 | font-size: larger ; | |
203 | color: maroon ; | |
204 | text-align: center } | |
205 | ||
206 | p.sidebar-title { | |
207 | font-family: sans-serif ; | |
208 | font-weight: bold ; | |
209 | font-size: larger } | |
210 | ||
211 | p.sidebar-subtitle { | |
212 | font-family: sans-serif ; | |
213 | font-weight: bold } | |
214 | ||
215 | p.topic-title { | |
216 | font-weight: bold } | |
217 | ||
218 | pre.address { | |
219 | margin-bottom: 0 ; | |
220 | margin-top: 0 ; | |
221 | font-family: serif ; | |
222 | font-size: 100% } | |
223 | ||
224 | pre.literal-block, pre.doctest-block { | |
225 | margin-left: 2em ; | |
226 | margin-right: 2em ; | |
227 | background-color: #eeeeee } | |
228 | ||
229 | span.classifier { | |
230 | font-family: sans-serif ; | |
231 | font-style: oblique } | |
232 | ||
233 | span.classifier-delimiter { | |
234 | font-family: sans-serif ; | |
235 | font-weight: bold } | |
236 | ||
237 | span.interpreted { | |
238 | font-family: sans-serif } | |
239 | ||
240 | span.option { | |
241 | white-space: nowrap } | |
242 | ||
243 | span.pre { | |
244 | white-space: pre } | |
245 | ||
246 | span.problematic { | |
247 | color: red } | |
248 | ||
249 | span.section-subtitle { | |
250 | /* font-size relative to parent (h1..h6 element) */ | |
251 | font-size: 80% } | |
252 | ||
253 | table.citation { | |
254 | border-left: solid 1px gray; | |
255 | margin-left: 1px } | |
256 | ||
257 | table.docinfo { | |
258 | margin: 2em 4em } | |
259 | ||
260 | table.docutils { | |
261 | margin-top: 0.5em ; | |
262 | margin-bottom: 0.5em } | |
263 | ||
264 | table.footnote { | |
265 | border-left: solid 1px black; | |
266 | margin-left: 1px } | |
267 | ||
268 | table.docutils td, table.docutils th, | |
269 | table.docinfo td, table.docinfo th { | |
270 | padding-left: 0.5em ; | |
271 | padding-right: 0.5em ; | |
272 | vertical-align: top } | |
273 | ||
274 | table.docutils th.field-name, table.docinfo th.docinfo-name { | |
275 | font-weight: bold ; | |
276 | text-align: left ; | |
277 | white-space: nowrap ; | |
278 | padding-left: 0 } | |
279 | ||
280 | h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, | |
281 | h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { | |
282 | font-size: 100% } | |
283 | ||
284 | tt.docutils { | |
285 | background-color: #eeeeee } | |
286 | ||
287 | ul.auto-toc { | |
288 | list-style-type: none } | |
289 | ||
290 | </style> | |
291 | </head> | |
292 | <body> | |
293 | <div class="document" id="wxpython-2-6-migration-guide"> | |
294 | <h1 class="title">wxPython 2.6 Migration Guide</h1> | |
295 | <p>This document will help explain some of the major changes in wxPython | |
296 | 2.6 since the 2.4 series and let you know what you need to do to adapt | |
297 | your programs to those changes. Be sure to also check in the <a class="reference" href="CHANGES.html">CHANGES</a> | |
298 | file like usual to see info about the not so major changes and other | |
299 | things that have been added to wxPython.</p> | |
300 | <div class="section"> | |
301 | <h1><a id="wxname-change" name="wxname-change">wxName Change</a></h1> | |
302 | <p>The <strong>wxWindows</strong> project and library is now known as | |
303 | <strong>wxWidgets</strong>. Please see <a class="reference" href="http://www.wxwidgets.org/name.htm">here</a> for more details.</p> | |
304 | <p>This won't really affect wxPython all that much, other than the fact | |
305 | that the wxwindows.org domain name has changed to wxwidgets.org, | |
306 | so mail list, CVS, and etc. addresses have also changed. We're going | |
307 | to try and smooth the transition as much as possible, but I wanted you | |
308 | all to be aware of this change if you run into any issues.</p> | |
309 | </div> | |
310 | <div class="section"> | |
311 | <h1><a id="module-initialization" name="module-initialization">Module Initialization</a></h1> | |
312 | <p>The import-startup-bootstrap process employed by wxPython was changed | |
313 | such that wxWidgets and the underlying gui toolkit are <strong>not</strong> | |
314 | initialized until the wx.App object is created (but before wx.App.OnInit | |
315 | is called.) This was required because of some changes that were made | |
316 | to the C++ wxApp class.</p> | |
317 | <p>There are both benefits and potential problems with this change. The | |
318 | benefits are that you can import wxPython without requiring access to | |
319 | a GUI (for checking version numbers, etc.) and that in a | |
320 | multi-threaded environment the thread that creates the app object will | |
321 | now be the GUI thread instead of the one that imports wxPython. Some | |
322 | potential problems are that the C++ side of the "stock-objects" | |
323 | (wx.BLUE_PEN, wx.TheColourDatabase, etc.) are not initialized until | |
324 | the wx.App object is created, so you should not use them until after | |
325 | you have created your wx.App object. If you do then an exception will | |
326 | be raised telling you that the C++ object has not been initialized | |
327 | yet.</p> | |
328 | <p>Also, you will probably not be able to do any kind of GUI or bitmap | |
329 | operation unless you first have created an app object, (even on | |
330 | Windows where most anything was possible before.)</p> | |
331 | <p><strong>[Changed in 2.5.2.x]</strong> All the Window and GDI (pen, bitmap, etc.) | |
332 | class constructors and also many toplevel functions and static methods | |
333 | will now check that a wx.App object has already been created and will | |
334 | raise a wx.PyNoAppError exception if not.</p> | |
335 | </div> | |
336 | <div class="section"> | |
337 | <h1><a id="swig-1-3" name="swig-1-3">SWIG 1.3</a></h1> | |
338 | <p>wxPython is now using SWIG 1.3.x from CVS (with several of my own | |
339 | customizations added that I hope to get folded back into the main SWIG | |
340 | distribution.) This has some far reaching ramifications:</p> | |
341 | <blockquote> | |
342 | <p>All classes derive from object and so all are now "new-style | |
343 | classes." This also allows you to use mixin classes that are | |
344 | new-style and to use properties, staticmethod, etc.</p> | |
345 | <p>Public data members of the C++ classes are wrapped as Python | |
346 | properties using property() instead of using | |
347 | __getattr__/__setattr__ hacks like before. Normally you shouldn't | |
348 | notice any difference, but if you were previously doing something | |
349 | with __getattr__/__setattr__ in derived classes then you may have | |
350 | to adjust things.</p> | |
351 | <p>Static C++ methods are wrapped using the staticmethod() feature of | |
352 | Python and so are accessible as ClassName.MethodName as expected. | |
353 | They are still also available as top level functions named like | |
354 | ClassName_MethodName as before.</p> | |
355 | <p>The relationship between the wxFoo and wxFooPtr classes have | |
356 | changed for the better. Specifically, all instances that you see | |
357 | will be wx.Foo even if they are created internally using wx.FooPtr, | |
358 | because wx.FooPtr.__init__ will change the instance's __class__ as | |
359 | part of the initialization. If you have any code that checks | |
360 | class type using something like isinstance(obj, wx.FooPtr) you will | |
361 | need to change it to isinstance(obj, wx.Foo).</p> | |
362 | </blockquote> | |
363 | </div> | |
364 | <div class="section"> | |
365 | <h1><a id="binding-events" name="binding-events">Binding Events</a></h1> | |
366 | <p>All of the EVT_* functions are now instances of the wx.PyEventBinder | |
367 | class. They have a __call__ method so they can still be used as | |
368 | functions like before, but making them instances adds some | |
369 | flexibility that I expect to take advantave of in the future.</p> | |
370 | <p>wx.EvtHandler (the base class for wx.Window) now has a Bind method that | |
371 | makes binding events to windows a little easier. Here is its | |
372 | definition and docstring:</p> | |
373 | <pre class="literal-block"> | |
374 | def Bind(self, event, handler, source=None, id=wxID_ANY, id2=wxID_ANY): | |
375 | """ | |
376 | Bind an event to an event handler. | |
377 | ||
378 | event One of the EVT_* objects that specifies the | |
379 | type of event to bind. | |
380 | ||
381 | handler A callable object to be invoked when the event | |
382 | is delivered to self. Pass None to disconnect an | |
383 | event handler. | |
384 | ||
385 | source Sometimes the event originates from a different window | |
386 | than self, but you still want to catch it in self. (For | |
387 | example, a button event delivered to a frame.) By | |
388 | passing the source of the event, the event handling | |
389 | system is able to differentiate between the same event | |
390 | type from different controls. | |
391 | ||
392 | id,id2 Used for menu IDs or for event types that require a | |
393 | range of IDs | |
394 | ||
395 | """ | |
396 | </pre> | |
397 | <p>Some examples of its use:</p> | |
398 | <pre class="literal-block"> | |
399 | self.Bind(wx.EVT_SIZE, self.OnSize) | |
400 | self.Bind(wx.EVT_BUTTON, self.OnButtonClick, theButton) | |
401 | self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT) | |
402 | </pre> | |
403 | <p>The wx.Menu methods that add items to a wx.Menu have been modified | |
404 | such that they return a reference to the wx.MenuItem that was created. | |
405 | Additionally menu items and toolbar items have been modified to | |
406 | automatically generate a new ID if -1 is given, similar to using -1 | |
407 | with window classess. This means that you can create menu or toolbar | |
408 | items and event bindings without having to predefine a unique menu ID, | |
409 | although you still can use IDs just like before if you want. For | |
410 | example, these are all equivallent other than their specific ID | |
411 | values:</p> | |
412 | <pre class="literal-block"> | |
413 | 1. | |
414 | item = menu.Append(-1, "E&xit", "Terminate the App") | |
415 | self.Bind(wx.EVT_MENU, self.OnExit, item) | |
416 | ||
417 | 2. | |
418 | item = menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App") | |
419 | self.Bind(wx.EVT_MENU, self.OnExit, item) | |
420 | ||
421 | 3. | |
422 | menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App") | |
423 | self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT) | |
424 | </pre> | |
425 | <p>If you create your own custom event types and EVT_* functions, and you | |
426 | want to be able to use them with the Bind method above then you should | |
427 | change your EVT_* to be an instance of wx.PyEventBinder instead of a | |
428 | function. For example, if you used to have something like this:</p> | |
429 | <pre class="literal-block"> | |
430 | myCustomEventType = wxNewEventType() | |
431 | def EVT_MY_CUSTOM_EVENT(win, id, func): | |
432 | win.Connect(id, -1, myCustomEventType, func) | |
433 | </pre> | |
434 | <p>Change it like so:</p> | |
435 | <pre class="literal-block"> | |
436 | myCustomEventType = wx.NewEventType() | |
437 | EVT_MY_CUSTOM_EVENT = wx.PyEventBinder(myCustomEventType, 1) | |
438 | </pre> | |
439 | <p>The second parameter is an integer in [0, 1, 2] that specifies the | |
440 | number of IDs that are needed to be passed to Connect.</p> | |
441 | <p><strong>[Changed in 2.5.2.x]</strong> There is also an Unbind method added to | |
442 | wx.EvtHandler that can be used to disconenct event handlers. It looks | |
443 | like this:</p> | |
444 | <pre class="literal-block"> | |
445 | def Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY): | |
446 | """ | |
447 | Disconencts the event handler binding for event from self. | |
448 | Returns True if successful. | |
449 | """ | |
450 | </pre> | |
451 | </div> | |
452 | <div class="section"> | |
453 | <h1><a id="the-wx-namespace" name="the-wx-namespace">The wx Namespace</a></h1> | |
454 | <p>The second phase of the wx Namespace Transition has begun. That means | |
455 | that the real names of the classes and other symbols do not have the | |
456 | 'wx' prefix and the modules are located in a Python package named | |
457 | wx. There is still a Python package named wxPython with modules | |
458 | that have the names with the wx prefix for backwards compatibility. | |
459 | Instead of dynamically changing the names at module load time like in | |
460 | 2.4, the compatibility modules are generated at build time and contain | |
461 | assignment statements like this:</p> | |
462 | <pre class="literal-block"> | |
463 | wxWindow = wx._core.Window | |
464 | </pre> | |
465 | <p>Don't let the "_core" in the name bother you. That and some other | |
466 | modules are implementation details, and everything that was in the | |
467 | wxPython.wx module before will still be in the wx package namespace | |
468 | after this change. So from your code you would use it as wx.Window or | |
469 | wxWindow if you import from the wxPython.wx module.</p> | |
470 | <p>A few notes about how all of this was accomplished might be | |
471 | interesting... SWIG is now run twice for each module that it is | |
472 | generating code for. The first time it outputs an XML representaion | |
473 | of the parse tree, which can be up to 20MB and 300K lines in size! | |
474 | That XML is then run through a little Python script that creates a | |
475 | file full of SWIG %rename directives that take the wx off of the | |
476 | names, and also generates the Python compatibility file described | |
477 | above that puts the wx back on the names. SWIG is then run a second | |
478 | time to generate the C++ code to implement the extension module, and | |
479 | uses the %rename directives that were generated in the first step.</p> | |
480 | <p>Not every name is handled correctly (but the bulk of them are) and so | |
481 | some work has to be done by hand, especially for the reverse-renamers. | |
482 | So expect a few flaws here and there until everything gets sorted out.</p> | |
483 | <p>In summary, the wx package and names without the "wx" prefix are now | |
484 | the official form of the wxPython classes. For example:</p> | |
485 | <pre class="literal-block"> | |
486 | import wx | |
487 | ||
488 | class MyFrame(wx.Frame): | |
489 | def __init__(self, parent, title): | |
490 | wx.Frame.__init__(self, parent, -1, title) | |
491 | p = wx.Panel(self, -1) | |
492 | b = wx.Button(p, -1, "Do It", (10,10)) | |
493 | self.Bind(wx.EVT_BUTTON, self.JustDoIt, b) | |
494 | ||
495 | def JustDoIt(self, evt): | |
496 | print "It's done!" | |
497 | ||
498 | app = wx.PySimpleApp() | |
499 | f = MyFrame(None, "What's up?") | |
500 | f.Show() | |
501 | app.MainLoop() | |
502 | </pre> | |
503 | <p>You shouldn't need to migrate all your modules over to use the new | |
504 | package and names right away as there are modules in place that try to | |
505 | provide as much backwards compatibility of the names as possible. If | |
506 | you rewrote the above sample using "from wxPython.wx import * ", the | |
507 | old wxNames, and the old style of event binding it will still work | |
508 | just fine.</p> | |
509 | </div> | |
510 | <div class="section"> | |
511 | <h1><a id="new-wx-dc-methods" name="new-wx-dc-methods">New wx.DC Methods</a></h1> | |
512 | <p><strong>[Changed in 2.5.2.x]</strong> In wxPython 2.5.1.5 there was a new | |
513 | implementation of the wx.DC Draw and other methods that broke | |
514 | backwards compatibility in the name of consistency. That change has | |
515 | been reverted and the wx.DC Draw methods with 2.4 compatible | |
516 | signatures have been restored. In addition a new set of methods have | |
517 | been added that take wx.Point and/or wx.Size parameters instead of | |
518 | separate integer parameters. The Draw and etc. methods now available | |
519 | in the wx.DC class are:</p> | |
520 | <pre class="literal-block"> | |
521 | FloodFill(self, x, y, colour, style = wx.FLOOD_SURFACE) | |
522 | FoodFillPoint(self, pt, colour, style = wx.FLOOD_SURFACE) | |
523 | ||
524 | GetPixel(self, x,y) | |
525 | GetPixelPoint(self, pt) | |
526 | ||
527 | DrawLine(self, x1, y1, x2, y2) | |
528 | DrawLinePoint(self, pt1, pt2) | |
529 | ||
530 | CrossHair(self, x, y) | |
531 | CrossHairPoint(self, pt) | |
532 | ||
533 | DrawArc(self, x1, y1, x2, y2, xc, yc) | |
534 | DrawArcPoint(self, pt1, pt2, centre) | |
535 | ||
536 | DrawCheckMark(self, x, y, width, height) | |
537 | DrawCheckMarkRect(self, rect) | |
538 | ||
539 | DrawEllipticArc(self, x, y, w, h, sa, ea) | |
540 | DrawEllipticArcPointSize(self, pt, sz, sa, ea) | |
541 | ||
542 | DrawPoint(self, x, y) | |
543 | DrawPointPoint(self, pt) | |
544 | ||
545 | DrawRectangle(self, x, y, width, height) | |
546 | DrawRectangleRect(self, rect) | |
547 | DrawRectanglePointSize(self, pt, sz) | |
548 | ||
549 | DrawRoundedRectangle(self, x, y, width, height, radius) | |
550 | DrawRoundedRectangleRect(self, r, radius) | |
551 | DrawRoundedRectanglePointSize(self, pt, sz, radius) | |
552 | ||
553 | DrawCircle(self, x, y, radius) | |
554 | DrawCirclePoint(self, pt, radius) | |
555 | ||
556 | DrawEllipse(self, x, y, width, height) | |
557 | DrawEllipseRect(self, rect) | |
558 | DrawEllipsePointSize(self, pt, sz) | |
559 | ||
560 | DrawIcon(self, icon, x, y) | |
561 | DrawIconPoint(self, icon, pt) | |
562 | ||
563 | DrawBitmap(self, bmp, x, y, useMask = False) | |
564 | DrawBitmapPoint(self, bmp, pt, useMask = False) | |
565 | ||
566 | DrawText(self, text, x, y) | |
567 | DrawTextPoint(self, text, pt) | |
568 | ||
569 | DrawRotatedText(self, text, x, y, angle) | |
570 | DrawRotatedTextPoint(self, text, pt, angle) | |
571 | ||
572 | bool Blit(self, xdest, ydest, width, height, sourceDC, xsrc, ysrc, | |
573 | rop = wx.COPY, useMask = False, xsrcMask = -1, ysrcMask = -1) | |
574 | BlitPointSize(self, destPt, sz, sourceDC, srcPt, rop = wx.COPY, | |
575 | useMask = False, srcPtMask = wxDefaultPosition) | |
576 | ||
577 | ||
578 | SetClippingRegion(self, x, y, width, height) | |
579 | SetClippingRegionPointSize(self, pt, sz) | |
580 | SetClippingRegionAsRegion(self, region) | |
581 | SetClippingRect(self, rect) | |
582 | </pre> | |
583 | </div> | |
584 | <div class="section"> | |
585 | <h1><a id="building-extending-and-embedding-wxpython" name="building-extending-and-embedding-wxpython">Building, Extending and Embedding wxPython</a></h1> | |
586 | <p>wxPython's setup.py script now expects to use existing libraries for | |
587 | the contribs (gizmos, stc, xrc, etc.) rather than building local | |
588 | copies of them. If you build your own copies of wxPython please be | |
589 | aware that you now need to also build the stc, xrc, animate and gizmos | |
590 | libraries in addition to the main wx lib.</p> | |
591 | <p>The wxPython.h and other header files are now in | |
592 | .../wxPython/include/wx/wxPython instead of in wxPython/src. You | |
593 | should include it via the "wx/wxPython/wxPython.h" path and add | |
594 | .../wxPython/include to your list of include paths. On OSX and | |
595 | unix-like systems the wxPython headers are installed to the same place | |
596 | that the wxWidgets headers are installed, so if you are building | |
597 | wxPython compatible extensions on those platforms then your include | |
598 | path should already be set properly.</p> | |
599 | <p>If you are also using SWIG for your extension then you'll need to | |
600 | adapt how the wxPython .i files are imported into your .i files. See | |
601 | the wxPython sources for examples. Your modules will need to at least | |
602 | <tt class="docutils literal"><span class="pre">%import</span> <span class="pre">core.i</span></tt>, and possibly others if you need the definition of | |
603 | other classes. Since you will need them to build your modules using | |
604 | SWIG, the main wxPython .i files are also installed with the wxPython | |
605 | headers in an i_files sibdirectory. It should be enough to pass a | |
606 | -I/pathname on the command line for SWIG to find the files.</p> | |
607 | <p>The bulk of wxPython's setup.py has been moved to another module, | |
608 | wx/build/config.py. This module will be installed as part of wxPython | |
609 | so 3rd party modules that wish to use the same setup/configuration | |
610 | code can do so simply by importing this module from their own setup.py | |
611 | scripts using <tt class="docutils literal"><span class="pre">import</span> <span class="pre">wx.build.config</span></tt>.</p> | |
612 | <p>You no longer need to call wxClassInfo::CleanUpClasses() and | |
613 | wxClassInfo::InitializeClasses() in your extensions or when embedding | |
614 | wxPython.</p> | |
615 | <p>The usage of wxPyBeginAllowThreads and wxPyEndAllowThreads has changed | |
616 | slightly. wxPyBeginAllowThreads now returns a boolean value that must | |
617 | be passed to the coresponding wxPyEndAllowThreads function call. This | |
618 | is to help do the RightThing when calls to these two functions are | |
619 | nested, or if calls to external code in other extension modules that | |
620 | are wrapped in the standard Py_(BEGIN|END)_ALLOW_THERADS may result in | |
621 | wx event handlers being called (such as during the call to | |
622 | os.startfile.)</p> | |
623 | </div> | |
624 | <div class="section"> | |
625 | <h1><a id="two-or-three-phase-create" name="two-or-three-phase-create">Two (or Three!) Phase Create</a></h1> | |
626 | <p>If you use the Precreate/Create method of instantiating a window, (for | |
627 | example, to set an extended style flag, or for XRC handlers) then | |
628 | there is now a new method named PostCreate to help with transplanting | |
629 | the brain of the prewindow instance into the derived window instance. | |
630 | For example:</p> | |
631 | <pre class="literal-block"> | |
632 | class MyDialog(wx.Dialog): | |
633 | def __init__(self, parent, ID, title, pos, size, style): | |
634 | pre = wx.PreDialog() | |
635 | pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) | |
636 | pre.Create(parent, ID, title, pos, size, style) | |
637 | self.PostCreate(pre) | |
638 | </pre> | |
639 | </div> | |
640 | <div class="section"> | |
641 | <h1><a id="sizers" name="sizers">Sizers</a></h1> | |
642 | <p>The hack allowing the old "option" keyword parameter has been removed. | |
643 | If you use keyword args with wx.Sizer Add, Insert, or Prepend methods | |
644 | then you will need to use the <tt class="docutils literal"><span class="pre">proportion</span></tt> name instead of | |
645 | <tt class="docutils literal"><span class="pre">option</span></tt>. (The <tt class="docutils literal"><span class="pre">proportion</span></tt> keyword was also allowed in 2.4.2.4.)</p> | |
646 | <p>When adding a spacer to a sizer you now need to use a wx.Size or a | |
647 | 2-integer sequence instead of separate width and height parameters. | |
648 | This was optionally allowed in 2.4, but now it is required. This | |
649 | allows for more consistency in how you add the various types of items | |
650 | to a sizer. The first parameter defines the item (instead of the | |
651 | possibily first two, depending on if you are doing a spacer or not,) | |
652 | and that item can either be a window, a sizer or a spacer (which can | |
653 | be a sequence or a wx.Size.) Removing the option for separate width | |
654 | and height parameters greatly simplified the wrapper code.</p> | |
655 | <p>The wx.GridBagSizer class (very similar to the RowColSizer in the | |
656 | library) has been added to C++ and wrapped for wxPython. It can also | |
657 | be used from XRC.</p> | |
658 | <p>You should not use AddWindow, AddSizer, AddSpacer (and similar for | |
659 | Insert, Prepend, and etc.) methods any longer. Just use Add and the | |
660 | wrappers will figure out what to do. <strong>[Changed in 2.5.2.x]</strong> | |
661 | AddWindow, AddSizer, AddSpacer and etc. will now issue a | |
662 | DeprecationWarning. <strong>[Changed in 2.5.4.x]</strong> These methods have now | |
663 | been undeprecated at the request of Riaan Booysen, the Boa Constructor | |
664 | team lead. They are now just simple compatibility aliases for Add, | |
665 | and etc.</p> | |
666 | <p><strong>[Changed in 2.5.2.x]</strong> The Sizers have had some fundamental internal | |
667 | changes in the 2.5.2.x release intended to make them do more of the | |
668 | "Right Thing" but also be as backwards compatible as possible. | |
669 | First a bit about how things used to work:</p> | |
670 | <blockquote> | |
671 | <ul class="simple"> | |
672 | <li>The size that a window had when Add()ed to the sizer was assumed | |
673 | to be its minimal size, and that size would always be used by | |
674 | default when calculating layout size and positions, and the | |
675 | sizer itself would keep track of that minimal size.</li> | |
676 | <li>If the window item was added with the <tt class="docutils literal"><span class="pre">wx.ADJUST_MINSIZE</span></tt> | |
677 | flag then when layout was calculated the item's <tt class="docutils literal"><span class="pre">GetBestSize</span></tt> | |
678 | would be used to reset the minimal size that the sizer used.</li> | |
679 | </ul> | |
680 | </blockquote> | |
681 | <p>The main thrust of the new Sizer changes was to make behavior like | |
682 | <tt class="docutils literal"><span class="pre">wx.ADJUST_MINSIZE</span></tt> be the default, and also to push the tracking of | |
683 | the minimal size to the window itself (since it knows its own needs) | |
684 | instead of having the sizer take care of it. Consequently these | |
685 | changes were made:</p> | |
686 | <blockquote> | |
687 | <ul class="simple"> | |
688 | <li>The <tt class="docutils literal"><span class="pre">wx.FIXED_MINSIZE</span></tt> flag was added to allow for the old | |
689 | behavior. When this flag is used the size a window has when | |
690 | added to the sizer will be treated as its minimal size and it | |
691 | will not be readjusted on each layout.</li> | |
692 | <li>The min size stored in <tt class="docutils literal"><span class="pre">wx.Window</span></tt> and settable with | |
693 | <tt class="docutils literal"><span class="pre">SetSizeHints</span></tt> or <tt class="docutils literal"><span class="pre">SetMinSize</span></tt> will by default be used by | |
694 | the sizer (if it was set) as the minimal size of the sizer item. | |
695 | If the min size was not set (or was only partially set) then the | |
696 | window's best size is fetched and it is used instead of (or | |
697 | blended with) the min size. <tt class="docutils literal"><span class="pre">wx.Window.GetBestFittingSize</span></tt> | |
698 | was added to facilitate getting the size to be used by the | |
699 | sizers.</li> | |
700 | <li>The best size of a window is cached so it doesn't need to | |
701 | recaculated on every layout. <tt class="docutils literal"><span class="pre">wx.Window.InvalidateBestSize</span></tt> | |
702 | was added and should be called (usually just internally in | |
703 | control methods) whenever something is done that would make the | |
704 | best size change.</li> | |
705 | <li>All wxControls were changed to set the minsize to what is passed | |
706 | to the constructor or Create method, and also to set the real | |
707 | size of the control to the blending of the min size and best | |
708 | size. <tt class="docutils literal"><span class="pre">wx.Window.SetBestFittingSize</span></tt> was added to help with | |
709 | this, although most controls don't need to call it directly | |
710 | because it is called indirectly via the <tt class="docutils literal"><span class="pre">SetInitialSize</span></tt> | |
711 | called in the base classes.</li> | |
712 | </ul> | |
713 | </blockquote> | |
714 | <p>At this time, the only situation known not to work the same as before | |
715 | is the following:</p> | |
716 | <pre class="literal-block"> | |
717 | win = SomeWidget(parent) | |
718 | win.SetSize(SomeNonDefaultSize) | |
719 | sizer.Add(win) | |
720 | </pre> | |
721 | <p>In this case the old code would have used the new size as the minimum, | |
722 | but now the sizer will use the default size as the minimum rather than | |
723 | the size set later. It is an easy fix though, just move the | |
724 | specification of the size to the constructor (assuming that SomeWidget | |
725 | will set its minsize there like the rest of the controls do) or call | |
726 | <tt class="docutils literal"><span class="pre">SetMinSize</span></tt> instead of <tt class="docutils literal"><span class="pre">SetSize</span></tt>.</p> | |
727 | <p>In order to fit well with this new scheme of things, all wxControls or | |
728 | custom controls should do the following things. (Depending on how | |
729 | they are used you may also want to do the same thing for non-control | |
730 | custom windows.)</p> | |
731 | <blockquote> | |
732 | <ul> | |
733 | <li><p class="first">Either override or inherit a meaningful <tt class="docutils literal"><span class="pre">DoGetBestSize</span></tt> method | |
734 | that calculates whatever size is "best" for the control. Once | |
735 | that size is calculated then there should normally be a call to | |
736 | <tt class="docutils literal"><span class="pre">CacheBestSize</span></tt> to save it for later use, unless for some | |
737 | reason you want the best size to be recalculated on every | |
738 | layout.</p> | |
739 | <p>Note: In order to successfully override <tt class="docutils literal"><span class="pre">DoGetBestSize</span></tt> in | |
740 | Python the class needs to be derived from <tt class="docutils literal"><span class="pre">wx.PyWindow</span></tt>, | |
741 | <tt class="docutils literal"><span class="pre">wx.PyControl</span></tt>, or etc. If your class instead derives from | |
742 | one of the standard wx classes then just be sure that the min | |
743 | size gets explicitly set to what would have been the best size | |
744 | and things should work properly in almost all situations.</p> | |
745 | </li> | |
746 | <li><p class="first">Any method that changes the attributes of the control such that | |
747 | the best size will change should call <tt class="docutils literal"><span class="pre">InvalidateBestSize</span></tt> so | |
748 | it will be recalculated the next time it is needed.</p> | |
749 | </li> | |
750 | <li><p class="first">The control's constructor and/or Create method should ensure | |
751 | that the minsize is set to the size passed in, and that the | |
752 | control is sized to a blending of the min size and best size. | |
753 | This can be done by calling <tt class="docutils literal"><span class="pre">SetBestFittingSize</span></tt>.</p> | |
754 | </li> | |
755 | </ul> | |
756 | </blockquote> | |
757 | </div> | |
758 | <div class="section"> | |
759 | <h1><a id="platforminfo" name="platforminfo">PlatformInfo</a></h1> | |
760 | <p>Added wx.PlatformInfo which is a tuple containing strings that | |
761 | describe the platform and build options of wxPython. This lets you | |
762 | know more about the build than just the __WXPORT__ value that | |
763 | wx.Platform contains, such as if it is a GTK2 build. For example, | |
764 | instead of:</p> | |
765 | <pre class="literal-block"> | |
766 | if wx.Platform == "__WXGTK__": | |
767 | ... | |
768 | </pre> | |
769 | <p>you should do this:</p> | |
770 | <pre class="literal-block"> | |
771 | if "__WXGTK__" in wx.PlatformInfo: | |
772 | ... | |
773 | </pre> | |
774 | <p>and you can specifically check for a wxGTK2 build by looking for | |
775 | "gtk2" in wx.PlatformInfo. Unicode builds are also detectable this | |
776 | way. If there are any other platform/toolkit/build flags that make | |
777 | sense to add to this tuple please let me know.</p> | |
778 | <p>BTW, wx.Platform will probably be deprecated in the future.</p> | |
779 | </div> | |
780 | <div class="section"> | |
781 | <h1><a id="activex" name="activex">ActiveX</a></h1> | |
782 | <p>Lindsay Mathieson's newest <a class="reference" href="http://members.optusnet.com.au/~blackpaw1/wxactivex.html">wxActiveX</a> class has been wrapped into a new | |
783 | extension module called wx.activex. It is very generic and dynamic | |
784 | and should allow hosting of arbitray ActiveX controls within your | |
785 | wxPython apps. So far I've tested it with IE, PDF, and Flash | |
786 | controls, (and there are new samples in the demo and also library | |
787 | modules supporting these.)</p> | |
788 | <p>The new wx.activex module contains a bunch of code, but the most | |
789 | important things to look at are ActiveXWindow and ActiveXEvent. | |
790 | ActiveXWindow derives from wxWindow and the constructor accepts a | |
791 | CLSID for the ActiveX Control that should be created. (There is also | |
792 | a CLSID class that can convert from a progID or a CLSID String.) The | |
793 | ActiveXWindow class simply adds methods that allow you to query some | |
794 | of the TypeInfo exposed by the ActiveX object, and also to get/set | |
795 | properties or call methods by name. The Python implementation | |
796 | automatically handles converting parameters and return values to/from | |
797 | the types expected by the ActiveX code as specified by the TypeInfo, | |
798 | (just bool, integers, floating point, strings and None/Empty so far, | |
799 | but more can be handled later.)</p> | |
800 | <p>That's pretty much all there is to the class, as I mentioned before it | |
801 | is very generic and dynamic. Very little is hard-coded and everything | |
802 | that is done with the actual ActiveX control is done at runtime and | |
803 | referenced by property or method name. Since Python is such a dynamic | |
804 | language this is a very good match. I thought for a while about doing | |
805 | some Python black-magic and making the specific methods/properties of | |
806 | the actual ActiveX control "appear" at runtime, but then decided that | |
807 | it would be better and more understandable to do it via subclassing. | |
808 | So there is a utility class in wx.activex that given an existing | |
809 | ActiveXWindow instance can generate a .py module containing a derived | |
810 | class with real methods and properties that do the Right Thing to | |
811 | reflect those calls to the real ActiveX control. There is also a | |
812 | script/tool module named genaxmodule that given a CLSID or progID and | |
813 | a class name, will generate the module for you. There are a few | |
814 | examples of the output of this tool in the wx.lib package, see | |
815 | iewin.py, pdfwin.py and flashwin.py.</p> | |
816 | <p>Currently the genaxmodule tool will tweak some of the names it | |
817 | generates, but this can be controled if you would like to do it | |
818 | differently by deriving your own class from GernerateAXModule, | |
819 | overriding some methods and then using this class from a tool like | |
820 | genaxmodule. [TODO: make specifying a new class on genaxmodule's | |
821 | command-line possible.] The current default behavior is that any | |
822 | event names that start with "On" will have the "On" dropped, property | |
823 | names are converted to all lower case, and if any name is a Python | |
824 | keyword it will have an underscore appended to it. GernerateAXModule | |
825 | does it's best when generating the code in the new module, but it can | |
826 | only be as good as the TypeInfo data available from the ActiveX | |
827 | control so sometimes some tweaking will be needed. For example, the | |
828 | IE web browser control defines the Flags parameter of the Navigate2 | |
829 | method as required, but MSDN says it is optional.</p> | |
830 | <p>It is intended that this new wx.activex module will replace both the | |
831 | older version of Lindsay's code available in iewin.IEHtmlWindow, and | |
832 | also the wx.lib.activexwraper module. Probably the biggest | |
833 | differences you'll ecounter in migrating activexwrapper-based code | |
834 | (besides events working better without causing deadlocks) is that | |
835 | events are no longer caught by overriding methods in your derived | |
836 | class. Instead ActiveXWindow uses the wx event system and you bind | |
837 | handlers for the ActiveX events exactly the same way you do for any wx | |
838 | event. There is just one extra step needed and that is creating an | |
839 | event ID from the ActiveX event name, and if you use the genaxmodule | |
840 | tool then this extra step will be handled for you there. For example, | |
841 | for the StatusTextChange event in the IE web browser control, this | |
842 | code is generated for you:</p> | |
843 | <pre class="literal-block"> | |
844 | wxEVT_StatusTextChange = wx.activex.RegisterActiveXEvent('StatusTextChange') | |
845 | EVT_StatusTextChange = wx.PyEventBinder(wxEVT_StatusTextChange, 1) | |
846 | </pre> | |
847 | <p>and you would use it in your code like this:</p> | |
848 | <pre class="literal-block"> | |
849 | self.Bind(iewin.EVT_StatusTextChange, self.UpdateStatusText, self.ie) | |
850 | </pre> | |
851 | <p>When the event happens and your event handler function is called the | |
852 | event properties from the ActiveX control (if any) are converted to | |
853 | attributes of the event object passed to the handler. (Can you say | |
854 | 'event' any more times in a single sentence? ;-) ) For example the | |
855 | StatusTextChange event will also send the text that should be put into | |
856 | the status line as an event parameter named "Text" and you can access | |
857 | it your handlers as an attribute of the event object like this:</p> | |
858 | <pre class="literal-block"> | |
859 | def UpdateStatusText(self, evt): | |
860 | self.SetStatusText(evt.Text) | |
861 | </pre> | |
862 | <p>Usually these event object attributes should be considered read-only, | |
863 | but some will be defined by the TypeInfo as output parameters. In | |
864 | those cases if you modify the event object's attribute then that value | |
865 | will be returned to the ActiveX control. For example, to prevent a | |
866 | new window from being opened by the IE web browser control you can do | |
867 | this in the handler for the iewin.EVT_NewWindow2 event:</p> | |
868 | <pre class="literal-block"> | |
869 | def OnNewWindow2(self, evt): | |
870 | evt.Cancel = True | |
871 | </pre> | |
872 | <p>So how do you know what methods, events and properties that an ActiveX | |
873 | control supports? There is a funciton in wx.activex named GetAXInfo | |
874 | that returns a printable summary of the TypeInfo from the ActiveX | |
875 | instance passed in. You can use this as an example of how to browse | |
876 | the TypeInfo provided, and there is also a copy of this function's | |
877 | output appended as a comment to the modules produced by the | |
878 | genaxmodule tool. Beyond that you'll need to consult the docs | |
879 | provided by the makers of the ActiveX control that you are using.</p> | |
880 | </div> | |
881 | <div class="section"> | |
882 | <h1><a id="png-images" name="png-images">PNG Images</a></h1> | |
883 | <p>Prior to 2.5 the PNG image handler would convert all alpha channel | |
884 | information to a mask when the image was loaded. Pixels that were | |
885 | more than halfway transparent would be made fully transparent by the | |
886 | mask and the rest would be made fully opaque.</p> | |
887 | <p>In 2.5 the image handler has been updated to preserve the alpha | |
888 | channel and will now only create a mask when all the pixels in the | |
889 | image are either fully transparent or fully opaque. In addition, the | |
890 | wx.DC.DrawBitmap and wx.DC.Blit methods are able to correctly blend | |
891 | the pixels in the image with partially transparent alpha values.</p> | |
892 | <p>If you are using a PNG with an alpha channel but you need to have a | |
893 | wx.Mask like you automatically got in 2.4 then you can do one of the | |
894 | following:</p> | |
895 | <blockquote> | |
896 | <ul class="simple"> | |
897 | <li>Edit the image and make all the partially transparent pixels be | |
898 | fully transparent.</li> | |
899 | <li>Use a different image type.</li> | |
900 | <li>Set a mask based on colour after you load the image.</li> | |
901 | </ul> | |
902 | </blockquote> | |
903 | </div> | |
904 | <div class="section"> | |
905 | <h1><a id="ogl-is-dead-long-live-ogl" name="ogl-is-dead-long-live-ogl">OGL is dead! LONG LIVE OGL!</a></h1> | |
906 | <p><strong>[Changed in 2.5.2.x]</strong></p> | |
907 | <p>The wx.ogl module was deprecated in version 2.5.2 in favor of the new | |
908 | Python port of the OGL library located at wx.lib.ogl contributed by | |
909 |