]>
Commit | Line | Data |
---|---|---|
1 | ===================== | |
2 | The wxPython Manual | |
3 | ===================== | |
4 | ||
5 | -------------------------------------------- | |
6 | A guide to wxPython for Python programmers | |
7 | -------------------------------------------- | |
8 | ||
9 | :Author: Patrick K. O'Brien | |
10 | :Contact: pobrien@orbtech.com | |
11 | :Organization: Orbtech_ | |
12 | :Date: $Date$ | |
13 | :Revision: $Revision$ | |
14 | :License: wxWindows Free Documentation Licence, Version 3 | |
15 | ||
16 | .. _Orbtech: http://www.orbtech.com/ | |
17 | ||
18 | .. contents:: | |
19 | ||
20 | ||
21 | Introduction | |
22 | ============ | |
23 | ||
24 | This is a guide to the wxPython GUI toolkit, written **by** a Python | |
25 | programmer **for** his fellow Python programmers. It began as a | |
26 | simple translation of the wxWidgets documentation (which is written | |
27 | for C++ programmers), and evolved from there. And while there's | |
28 | nothing wrong with C++... | |
29 | ||
30 | Okay, you got me there. I hate C++. That's why I use Python. If you | |
31 | like C++, go read the wxWidgets documentation. If you'd rather read a | |
32 | guide that's written with Python programmers in mind, keep reading | |
33 | this one. If you like it, feel free to send me freshly roasted coffee | |
34 | beans, dark chocolate, and large denomination currency. Better yet, | |
35 | buy huge quantities of my wxPython book (written with Robin Dunn) and | |
36 | send one to each of your friends, relatives, and coworkers. | |
37 | ||
38 | ||
39 | What is wxPython? | |
40 | ================= | |
41 | ||
42 | wxPython is a GUI toolkit for the Python programming language. It | |
43 | allows Python programmers to create programs with a robust, highly | |
44 | functional graphical user interface, simply and easily. It is | |
45 | implemented as a Python extension module (native code) that wraps the | |
46 | popular wxWidgets cross platform GUI library, which is written in C++. | |
47 | ||
48 | Like Python and wxWidgets, wxPython is Open Source, which means that | |
49 | it is free for anyone to use and the source code is available for | |
50 | anyone to look at and modify. And anyone can contribute fixes or | |
51 | enhnacments to the project. | |
52 | ||
53 | wxPython is a cross-platform toolkit. This means that the same | |
54 | program will run on multiple platforms without modification. | |
55 | Currently supported platforms are 32-bit Microsoft Windows, most Unix | |
56 | or unix-like systems, and Macintosh OS X. | |
57 | ||
58 | Since the language is Python, wxPython programs are simple, easy to | |
59 | write and easy to understand. | |
60 | ||
61 | ||
62 | wxPython requirements | |
63 | ===================== | |
64 | ||
65 | To make use of wxPython, you currently need one of the following | |
66 | setups. | |
67 | ||
68 | MS-Windows | |
69 | ---------- | |
70 | ||
71 | * A 486 or higher PC running MS Windows. | |
72 | * At least ?? MB of disk space. | |
73 | ||
74 | Linux or Unix | |
75 | ------------- | |
76 | ||
77 | * Almost any C++ compiler, including GNU C++ (EGCS 1.1.1 or above). | |
78 | * Almost any Unix workstation, and one of: GTK+ 1.2, GTK+ 2.0, Motif | |
79 | 1.2 or higher, Lesstif. | |
80 | * At least ?? MB of disk space. | |
81 | ||
82 | Mac OS X | |
83 | -------- | |
84 | ||
85 | * A PowerPC Mac running Mac OS X 10.x. | |
86 | * At least ?? MB of disk space. | |
87 | ||
88 | ||
89 | What is wxWidgets? | |
90 | ================== | |
91 | ||
92 | wxWidgets is a C++ framework providing GUI (Graphical User Interface) | |
93 | and other facilities on more than one platform. Version 2 currently | |
94 | supports all desktop versions of MS Windows, Unix with GTK+, Unix with | |
95 | Motif, and MacOS. An OS/2 port is in progress. | |
96 | ||
97 | wxWidgets was originally developed at the Artificial Intelligence | |
98 | Applications Institute, University of Edinburgh, for internal use, and | |
99 | was first made publicly available in 1992. Version 2 is a vastly | |
100 | improved version written and maintained by Julian Smart, Robert | |
101 | Roebling, Vadim Zeitlin, Vaclav Slavik and many others. | |
102 | ||
103 | Please note that in the following, "MS Windows" often refers to all | |
104 | platforms related to Microsoft Windows, including 16-bit and 32-bit | |
105 | variants, unless otherwise stated. All trademarks are acknowledged. | |
106 | ||
107 | ||
108 | Why another cross-platform development tool? | |
109 | ============================================ | |
110 | ||
111 | wxWidgets was developed to provide a cheap and flexible way to | |
112 | maximize investment in GUI application development. While a number of | |
113 | commercial class libraries already existed for cross-platform | |
114 | development, none met all of the following criteria: | |
115 | ||
116 | * low price | |
117 | * source availability | |
118 | * simplicity of programming | |
119 | * support for a wide range of compilers | |
120 | ||
121 | Since wxWidgets was started, several other free or almost-free GUI | |
122 | frameworks have emerged. However, none has the range of features, | |
123 | flexibility, documentation and the well-established development team | |
124 | that wxWidgets has. | |
125 | ||
126 | As open source software, wxWidgets has benefited from comments, ideas, | |
127 | bug fixes, enhancements and the sheer enthusiasm of users. This gives | |
128 | wxWidgets a certain advantage over its commercial competitors (and | |
129 | over free libraries without an independent development team), plus a | |
130 | robustness against the transience of one individual or company. This | |
131 | openness and availability of source code is especially important when | |
132 | the future of thousands of lines of application code may depend upon | |
133 | the longevity of the underlying class library. | |
134 | ||
135 | Version 2 goes much further than previous versions in terms of | |
136 | generality and features, allowing applications to be produced that are | |
137 | often indistinguishable from those produced using single-platform | |
138 | toolkits such as Motif, GTK+ and MFC. | |
139 | ||
140 | The importance of using a platform-independent class library cannot be | |
141 | overstated, since GUI application development is very time-consuming, | |
142 | and sustained popularity of particular GUIs cannot be guaranteed. | |
143 | Code can very quickly become obsolete if it addresses the wrong | |
144 | platform or audience. wxWidgets helps to insulate the programmer from | |
145 | these winds of change. Although wxWidgets may not be suitable for | |
146 | every application (such as an OLE-intensive program), it provides | |
147 | access to most of the functionality a GUI program normally requires, | |
148 | plus many extras such as network programming, PostScript output, and | |
149 | HTML rendering; and it can of course be extended as needs dictate. As | |
150 | a bonus, it provides a far cleaner and easier programming interface | |
151 | than the native APIs. Programmers may find it worthwhile to use | |
152 | wxWidgets even if they are developing on only one platform. | |
153 | ||
154 | It is impossible to sum up the functionality of wxWidgets in a few | |
155 | paragraphs, but here are some of the benefits: | |
156 | ||
157 | * Low cost (free, in fact!) | |
158 | * You get the source. | |
159 | * Available on a variety of popular platforms. | |
160 | * Works with almost all popular C++ compilers and Python. | |
161 | * Over 50 example programs. | |
162 | * Over 1000 pages of printable and on-line documentation. | |
163 | * Includes Tex2RTF, to allow you to produce your own documentation in | |
164 | Windows Help, HTML and Word RTF formats. | |
165 | * Simple-to-use, object-oriented API. | |
166 | * Flexible event system. | |
167 | * Graphics calls include lines, rounded rectangles, splines, | |
168 | polylines, etc. | |
169 | * Constraint-based and sizer-based layouts. | |
170 | * Print/preview and document/view architectures. | |
171 | * Toolbar, notebook, tree control, advanced list control classes. | |
172 | * PostScript generation under Unix, normal MS Windows printing on the | |
173 | PC. | |
174 | * MDI (Multiple Document Interface) support. | |
175 | * Can be used to create DLLs under Windows, dynamic libraries on Unix. | |
176 | * Common dialogs for file browsing, printing, colour selection, etc. | |
177 | * Under MS Windows, support for creating metafiles and copying them to | |
178 | the clipboard. | |
179 | * An API for invoking help from applications. | |
180 | * Ready-to-use HTML window (supporting a subset of HTML). | |
181 | * Dialog Editor for building dialogs. | |
182 | * Network support via a family of socket and protocol classes. | |
183 | * Support for platform independent image processing. | |
184 | * Built-in support for many file formats (BMP, PNG, JPEG, GIF, XPM, | |
185 | PNM, PCX). | |
186 | ||
187 | ||
188 | wxPython Overview | |
189 | ================= | |
190 | ||
191 | To set a wxPython application going, you will need to derive an App | |
192 | class and override App.OnInit. | |
193 | ||
194 | An application must have a top-level Frame or Dialog window. Each | |
195 | frame may contain one or more instances of classes such as Panel, | |
196 | SplitterWindow or other windows and controls. | |
197 | ||
198 | A frame can have a MenuBar, a ToolBar, a status line, and an Icon for | |
199 | when the frame is iconized. | |
200 | ||
201 | A Panel is used to place controls (classes derived from Control) which | |
202 | are used for user interaction. Examples of controls are Button, | |
203 | CheckBox, Choice, ListBox, RadioBox, Slider. | |
204 | ||
205 | Instances of Dialog can also be used for controls, and they have the | |
206 | advantage of not requiring a separate frame. | |
207 | ||
208 | Instead of creating a dialog box and populating it with items, it is | |
209 | possible to choose one of the convenient common dialog classes, such | |
210 | as MessageDialog and FileDialog. | |
211 | ||
212 | You never draw directly onto a window. Instead, you use a device | |
213 | context (DC). DC is the base for ClientDC, PaintDC, MemoryDC, | |
214 | PostScriptDC, MemoryDC, MetafileDC and PrinterDC. If your drawing | |
215 | functions have DC as a parameter, you can pass any of these DCs to the | |
216 | function, and thus use the same code to draw to several different | |
217 | devices. You can draw using the member functions of DC, such as | |
218 | DC.DrawLine and DC.DrawText. Control colour on a window (Colour) with | |
219 | brushes (Brush) and pens (Pen). | |
220 | ||
221 | .. To intercept events, you add a DECLARE_EVENT_TABLE macro to the | |
222 | window class declaration, and put a BEGIN_EVENT_TABLE | |
223 | ... END_EVENT_TABLE block in the implementation file. Between these | |
224 | macros, you add event macros which map the event (such as a mouse | |
225 | click) to a member function. These might override predefined event | |
226 | handlers such as for KeyEvent and MouseEvent. | |
227 | ||
228 | Most modern applications will have an on-line, hypertext help system; | |
229 | for this, you need Help and the HelpController class to control | |
230 | Help. | |
231 | ||
232 | GUI applications aren't all graphical wizardry. You'll also need | |
233 | lists and hash tables. But since you're working with Python, you | |
234 | should use the ones Python provides (list, tuple, dict), rather than | |
235 | the wxWidgets versions. Same goes for the database related classes. | |
236 | The basic rule of thumb is this: If you can do it directly in Python, | |
237 | you probably should. If there is a reason not to use a Python data | |
238 | type, wxPython will provide a wrapper for the wxWidgets class. | |
239 | ||
240 | You will undoubtedly need some platform-independent file functions, | |
241 | and you may find it handy to maintain and search a list of paths using | |
242 | PathList. There's a miscellany of operating system and other | |
243 | functions. | |
244 | ||
245 | See also Classes by Category for a list of classes. | |
246 | ||
247 | ||
248 | Utilities and libraries supplied with wxPython | |
249 | ============================================== | |
250 | ||
251 | In addition to the core wxWidgets library, a number of further | |
252 | libraries and utilities are supplied with each distribution. | |
253 | ||
254 | [Need to list these.] | |
255 | ||
256 | ||
257 | Creating and deleting wxPython objects | |
258 | ====================================== | |
259 | ||
260 | [This section needs to be reviewed.] | |
261 | ||
262 | .. In general, classes derived from wxWindow must dynamically | |
263 | allocated with new and deleted with delete. If you delete a window, | |
264 | all of its children and descendants will be automatically deleted, | |
265 | so you don't need to delete these descendants explicitly. | |
266 | ||
267 | .. When deleting a frame or dialog, use Destroy rather than delete so | |
268 | that the wxWidgets delayed deletion can take effect. This waits | |
269 | until idle time (when all messages have been processed) to actually | |
270 | delete the window, to avoid problems associated with the GUI | |
271 | sending events to deleted windows. | |
272 | ||
273 | .. If you decide to allocate a C++ array of objects (such as wxBitmap) | |
274 | that may be cleaned up by wxWidgets, make sure you delete the array | |
275 | explicitly before wxWidgets has a chance to do so on exit, since | |
276 | calling delete on array members will cause memory problems. | |
277 | ||
278 | .. wxColour can be created statically: it is not automatically cleaned | |
279 | up and is unlikely to be shared between other objects; it is | |
280 | lightweight enough for copies to be made. | |
281 | ||
282 | .. Beware of deleting objects such as a wxPen or wxBitmap if they are | |
283 | still in use. Windows is particularly sensitive to this: so make | |
284 | sure you make calls like wxDC::SetPen(wxNullPen) or | |
285 | wxDC::SelectObject(wxNullBitmap) before deleting a drawing object | |
286 | that may be in use. Code that doesn't do this will probably work | |
287 | fine on some platforms, and then fail under Windows. | |
288 | ||
289 | ||
290 | App overview | |
291 | ============ | |
292 | ||
293 | Classes: wx.App | |
294 | ||
295 | Application initialization | |
296 | -------------------------- | |
297 | ||
298 | The OnInit method defined for a class derived from wx.App will usually | |
299 | create a top window as a bare minimum. | |
300 | ||
301 | OnInit must return a boolean value to indicate whether processing | |
302 | should continue (True) or not (False). You call App.SetTopWindow to | |
303 | let wxPython know about the top window. | |
304 | ||
305 | An application closes by destroying all windows. Because all frames | |
306 | must be destroyed for the application to exit, it is advisable to use | |
307 | parent frames wherever possible when creating new frames, so that | |
308 | deleting the top level frame will automatically delete child frames. | |
309 | The alternative is to explicitly delete child frames in the top-level | |
310 | frame's CloseEvent handler. | |
311 | ||
312 | In emergencies the wx.Exit() function can be called to kill the | |
313 | application, however, normally the application shuts down | |
314 | automatically, see below. | |
315 | ||
316 | An example of defining an application follows:: | |
317 | ||
318 | import wx | |
319 | ||
320 | from frame import Frame | |
321 | ||
322 | class App(wx.App): | |
323 | """Application class.""" | |
324 | ||
325 | def OnInit(self): | |
326 | self.frame = Frame() | |
327 | self.frame.Show() | |
328 | self.SetTopWindow(self.frame) | |
329 | return True | |
330 | ||
331 | def main(): | |
332 | app = App() | |
333 | app.MainLoop() | |
334 | ||
335 | if __name__ == '__main__': | |
336 | main() | |
337 | ||
338 | ||
339 | Application shutdown | |
340 | -------------------- | |
341 | ||
342 | The application normally shuts down when the last of its top level | |
343 | windows is closed. This is normally the expected behaviour and means | |
344 | that it is enough to call Close() in response to the "Exit" menu | |
345 | command if your program has a single top level window. If this | |
346 | behaviour is not desirable, App.SetExitOnFrameDelete can be called to | |
347 | change it. Note that such logic doesn't apply for the windows shown | |
348 | before the program enters the main loop: in other words, you can | |
349 | safely show a dialog from App.OnInit and not be afraid that your | |
350 | application terminates when this dialog -- which is the last top level | |
351 | window for the moment -- is closed. | |
352 | ||
353 | Another aspect of the application shutdown is the OnExit which is | |
354 | called when the application exits but before wxPython cleans up its | |
355 | internal structures. You should delete all wxPython objects that you | |
356 | created by the time OnExit finishes. | |
357 | ||
358 | For example, this code may crash: | |
359 | ||
360 | [Need examples of objects needing cleanup to keep app from crashing.] | |
361 | ||
362 | ||
363 | Sizer overview | |
364 | ============== | |
365 | ||
366 | Classes: wx.Sizer, wx.GridSizer, wx.FlexGridSizer, wx.BoxSizer, | |
367 | wx.StaticBoxSizer, wx.NotebookSizer, wx.CreateButtonSizer | |
368 | ||
369 | ============== ====================================================== | |
370 | ||
371 | Sizer Abstract base class. | |
372 | ||
373 | GridSizer A sizer for laying out windows in a grid with all | |
374 | fields having the same size. | |
375 | ||
376 | FlexGridSizer A sizer for laying out windows in a flexible grid. | |
377 | ||
378 | BoxSizer A sizer for laying out windows in a row or column. | |
379 | ||
380 | StaticBoxSizer Same as BoxSizer, but with a surrounding static box. | |
381 | ||
382 | NotebookSizer Sizer to use with the Notebook control. | |
383 | ||
384 | ============== ====================================================== | |
385 | ||
386 | Sizers, as represented by the wx.Sizer class and its descendants in | |
387 | the wxPython class hierarchy, have become the method of choice to | |
388 | define the layout of controls in dialogs in wxPython because of their | |
389 | ability to create visually appealing dialogs independent of the | |
390 | platform, taking into account the differences in size and style of the | |
391 | individual controls. Editors such as wxDesigner, wxrcedit, XRCed and | |
392 | wxWorkshop create dialogs based exclusively on sizers, practically | |
393 | forcing the user to create platform independent layouts without | |
394 | compromises. | |
395 | ||
396 | ||
397 | The idea behind sizers | |
398 | ---------------------- | |
399 | ||
400 | The layout algorithm used by sizers in wxPython is closely related to | |
401 | layout systems in other GUI toolkits, such as Java's AWT, the GTK | |
402 | toolkit or the Qt toolkit. It is based upon the idea of individual | |
403 | subwindows reporting their minimal required size and their ability to | |
404 | get stretched if the size of the parent window has changed. This will | |
405 | most often mean that the programmer does not set the start-up size of | |
406 | a dialog, the dialog will rather be assigned a sizer and this sizer | |
407 | will be queried about the recommended size. This sizer in turn will | |
408 | query its children (which can be normal windows, empty space or other | |
409 | sizers) so that a hierarchy of sizers can be constructed. Note that | |
410 | wx.Sizer does not derive from wx.Window and thus does not interfere | |
411 | with tab ordering and requires very few resources compared to a real | |
412 | window on screen. | |
413 | ||
414 | What makes sizers so well fitted for use in wxPython is the fact that | |
415 | every control reports its own minimal size and the algorithm can | |
416 | handle differences in font sizes or different window (dialog item) | |
417 | sizes on different platforms without problems. For example, if the | |
418 | standard font as well as the overall design of Linux/GTK widgets | |
419 | requires more space than on Windows, the initial dialog size will | |
420 | automatically be bigger on Linux/GTK than on Windows. | |
421 | ||
422 | There are currently five different kinds of sizers available in | |
423 | wxPython. Each represents either a certain way to lay out dialog items | |
424 | in a dialog or it fulfils a special task such as wrapping a static box | |
425 | around a dialog item (or another sizer). These sizers will be | |
426 | discussed one by one in the text below. | |
427 | ||
428 | ||
429 | Common features | |
430 | --------------- | |
431 | ||
432 | All sizers are containers, that is, they are used to lay out one | |
433 | dialog item (or several dialog items), which they contain. Such items | |
434 | are sometimes referred to as the children of the sizer. Independent | |
435 | of how the individual sizers lay out their children, all children have | |
436 | certain features in common: | |
437 | ||
438 | ||
439 | A minimal size | |
440 | ~~~~~~~~~~~~~~ | |
441 | ||
442 | This minimal size is usually identical to the initial size of the | |
443 | controls and may either be set explicitly in the size field of the | |
444 | control constructor or may be calculated by wxPython, typically by | |
445 | setting the height and/or the width of the item to -1. Note that only | |
446 | some controls can calculate their size (such as a checkbox) whereas | |
447 | others (such as a listbox) don't have any natural width or height and | |
448 | thus require an explicit size. Some controls can calculate their | |
449 | height, but not their width (e.g. a single line text control): | |
450 | ||
451 | [Need graphics] | |
452 | ||
453 | ||
454 | A border | |
455 | ~~~~~~~~ | |
456 | ||
457 | The border is just empty space and is used to separate dialog items in | |
458 | a dialog. This border can either be all around, or at any combination | |
459 | of sides such as only above and below the control. The thickness of | |
460 | this border must be set explicitly, typically 5 points. The following | |
461 | samples show dialogs with only one dialog item (a button) and a border | |
462 | of 0, 5, and 10 pixels around the button: | |
463 | ||
464 | [Need graphics] | |
465 | ||
466 | ||
467 | An alignment | |
468 | ~~~~~~~~~~~~ | |
469 | ||
470 | Often, a dialog item is given more space than its minimal size plus | |
471 | its border. Depending on what flags are used for the respective dialog | |
472 | item, the dialog item can be made to fill out the available space | |
473 | entirely, i.e. it will grow to a size larger than the minimal size, or | |
474 | it will be moved to either the centre of the available space or to | |
475 | either side of the space. The following sample shows a listbox and | |
476 | three buttons in a horizontal box sizer; one button is centred, one is | |
477 | aligned at the top, one is aligned at the bottom: | |
478 | ||
479 | [Need graphics] | |
480 | ||
481 | ||
482 | A stretch factor | |
483 | ~~~~~~~~~~~~~~~~ | |
484 | ||
485 | If a sizer contains more than one child and it is offered more space | |
486 | than its children and their borders need, the question arises how to | |
487 | distribute the surplus space among the children. For this purpose, a | |
488 | stretch factor may be assigned to each child, where the default value | |
489 | of 0 indicates that the child will not get more space than its | |
490 | requested minimum size. A value of more than zero is interpreted in | |
491 | relation to the sum of all stretch factors in the children of the | |
492 | respective sizer, i.e. if two children get a stretch factor of 1, they | |
493 | will get half the extra space each independent of whether one control | |
494 | has a minimal sizer inferior to the other or not. The following | |
495 | sample shows a dialog with three buttons, the first one has a stretch | |
496 | factor of 1 and thus gets stretched, whereas the other two buttons | |
497 | have a stretch factor of zero and keep their initial width: | |
498 | ||
499 | [Need graphics] | |
500 | ||
501 | Within wxDesigner, this stretch factor gets set from the Option menu. | |
502 | ||
503 | ||
504 | BoxSizer | |
505 | -------- | |
506 | ||
507 | BoxSizer can lay out its children either vertically or horizontally, | |
508 | depending on what flag is being used in its constructor. When using a | |
509 | vertical sizer, each child can be centered, aligned to the right or | |
510 | aligned to the left. Correspondingly, when using a horizontal sizer, | |
511 | each child can be centered, aligned at the bottom or aligned at the | |
512 | top. The stretch factor described in the last paragraph is used for | |
513 | the main orientation, i.e. when using a horizontal box sizer, the | |
514 | stretch factor determines how much the child can be stretched | |
515 | horizontally. The following sample shows the same dialog as in the | |
516 | last sample, only the box sizer is a vertical box sizer now: | |
517 | ||
518 | [Need graphics] | |
519 | ||
520 | ||
521 | StaticBoxSizer | |
522 | -------------- | |
523 | ||
524 | StaticBoxSixer is the same as a BoxSizer, but surrounded by a static | |
525 | box. Here is a sample: | |
526 | ||
527 | [Need graphics] | |
528 | ||
529 | ||
530 | GridSizer | |
531 | --------- | |
532 | ||
533 | GridSizer is a two-dimensional sizer. All children are given the same | |
534 | size, which is the minimal size required by the biggest child, in this | |
535 | case the text control in the left bottom border. Either the number of | |
536 | columns or the number or rows is fixed and the grid sizer will grow in | |
537 | the respectively other orientation if new children are added: | |
538 | ||
539 | [Need graphics] | |
540 | ||
541 | ||
542 | FlexGridSizer | |
543 | ------------- | |
544 | ||
545 | Another two-dimensional sizer derived from GridSizer. The width of | |
546 | each column and the height of each row are calculated individually | |
547 | according the minimal requirements from the respectively biggest | |
548 | child. Additionally, columns and rows can be declared to be | |
549 | stretchable if the sizer is assigned a size different from that which | |
550 | it requested. The following sample shows the same dialog as the one | |
551 | above, but using a flex grid sizer: | |
552 | ||
553 | [Need graphics] | |
554 | ||
555 | ||
556 | NotebookSizer | |
557 | ------------- | |
558 | ||
559 | NotebookSizer can be used with notebooks. It calculates the size of | |
560 | each notebook page and sets the size of the notebook to the size of | |
561 | the biggest page plus some extra space required for the notebook tabs | |
562 | and decorations. | |
563 | ||
564 | [Need graphics] | |
565 | ||
566 | ||
567 | Programming with BoxSizer | |
568 | ------------------------- | |
569 | ||
570 | The basic idea behind a BoxSizer is that windows will most often be | |
571 | laid out in rather simple basic geometry, typically in a row or a | |
572 | column or several hierarchies of either. | |
573 | ||
574 | As an example, we will construct a dialog that will contain a text | |
575 | field at the top and two buttons at the bottom. This can be seen as a | |
576 | top-hierarchy column with the text at the top and buttons at the | |
577 | bottom and a low-hierarchy row with an OK button to the left and a | |
578 | Cancel button to the right. In many cases (particularly dialogs under | |
579 | Unix and normal frames) the main window will be resizable by the user | |
580 | and this change of size will have to get propagated to its children. | |
581 | In our case, we want the text area to grow with the dialog, whereas | |
582 | the button shall have a fixed size. In addition, there will be a thin | |
583 | border around all controls to make the dialog look nice and - to make | |
584 | matter worse - the buttons shall be centred as the width of the dialog | |
585 | changes. | |
586 | ||
587 | It is the unique feature of a box sizer, that it can grow in both | |
588 | directions (height and width) but can distribute its growth in the | |
589 | main direction (horizontal for a row) unevenly among its children. In | |
590 | our example case, the vertical sizer is supposed to propagate all its | |
591 | height changes to only the text area, not to the button area. This is | |
592 | determined by the proportion parameter when adding a window (or | |
593 | another sizer) to a sizer. It is interpreted as a weight factor, | |
594 | i.e. it can be zero, indicating that the window may not be resized at | |
595 | all, or above zero. If several windows have a value above zero, the | |
596 | value is interpreted relative to the sum of all weight factors of the | |
597 | sizer, so when adding two windows with a value of 1, they will both | |
598 | get resized equally much and each half as much as the sizer owning | |
599 | them. | |
600 | ||
601 | Then what do we do when a column sizer changes its width? This | |
602 | behaviour is controlled by flags (the second parameter of the Add() | |
603 | function): zero or no flag indicates that the window will preserve it | |
604 | is original size, wx.GROW flag (same as wx.EXPAND) forces the window | |
605 | to grow with the sizer, and wx.SHAPED flag tells the window to change | |
606 | it is size proportionally, preserving original aspect ratio. When | |
607 | wx.GROW flag is not used, the item can be aligned within available | |
608 | space. wx.ALIGN_LEFT, wx.ALIGN_TOP, wx.ALIGN_RIGHT, wx.ALIGN_BOTTOM, | |
609 | wx.ALIGN_CENTER_HORIZONTAL and wx.ALIGN_CENTER_VERTICAL do what they | |
610 | say. wx.ALIGN_CENTRE (same as wx.ALIGN_CENTER) is defined as | |
611 | (``wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL``). Default | |
612 | alignment is ``wx.ALIGN_LEFT | wx.ALIGN_TOP``. | |
613 | ||
614 | As mentioned above, any window belonging to a sizer may have border, | |
615 | and it can be specified which of the four sides may have this border, | |
616 | using the wx.TOP, wx.LEFT, wx.RIGHT and wx.BOTTOM constants or wx.ALL | |
617 | for all directions (and you may also use wx.NORTH, wx.WEST etc | |
618 | instead). These flags can be used in combination with the alignment | |
619 | flags above as the second parameter of the Add() method using the | |
620 | binary or operator (``|``). The sizer of the border also must be made | |
621 | known, and it is the third parameter in the Add() method. This means, | |
622 | that the entire behaviour of a sizer and its children can be | |
623 | controlled by the three parameters of the Add() method. | |
624 | ||
625 | [Show code and graphic here.] | |
626 | ||
627 | ||
628 | Programming with GridSizer | |
629 | -------------------------- | |
630 | ||
631 | GridSizer is a sizer which lays out its children in a two-dimensional | |
632 | table with all table fields having the same size, i.e. the width of | |
633 | each field is the width of the widest child, the height of each field | |
634 | is the height of the tallest child. | |
635 | ||
636 | [Show code and graphic here.] | |
637 | ||
638 | ||
639 | Programming with FlexGridSizer | |
640 | ------------------------------ | |
641 | ||
642 | FlexGridSizer is a sizer which lays out its children in a | |
643 | two-dimensional table with all table fields in one row having the same | |
644 | height and all fields in one column having the same width, but all | |
645 | rows or all columns are not necessarily the same height or width as in | |
646 | the GridSizer. | |
647 | ||
648 | [Show code and graphic here.] | |
649 | ||
650 | ||
651 | Programming with NotebookSizer | |
652 | ------------------------------ | |
653 | ||
654 | NotebookSizer is a specialized sizer to make sizers work in connection | |
655 | with using notebooks. This sizer is different from any other sizer as | |
656 | you must not add any children to it - instead, it queries the notebook | |
657 | class itself. The only thing this sizer does is to determine the size | |
658 | of the biggest page of the notebook and report an adjusted minimal | |
659 | size to a more toplevel sizer. | |
660 | ||
661 | In order to query the size of notebook page, this page needs to have | |
662 | its own sizer, otherwise the NotebookSizer will ignore it. Notebook | |
663 | pages get their sizer by assigning one to them using SetSizer() and | |
664 | setting the auto-layout option to True using SetAutoLayout(). Here is | |
665 | one example showing how to add a notebook page that the notebook sizer | |
666 | is aware of: | |
667 | ||
668 | [Show code and graphic here.] | |
669 | ||
670 | ||
671 | Programming with StaticBoxSizer | |
672 | ------------------------------- | |
673 | ||
674 | StaticBoxSizer is a sizer derived from BoxSizer but adds a static box | |
675 | around the sizer. Note that this static box has to be created | |
676 | separately. | |
677 | ||
678 | [Show code and graphic here.] | |
679 | ||
680 | ||
681 | Dialog.CreateButtonSizer | |
682 | ------------------------ | |
683 | ||
684 | As a convenience, the Dialog class has a CreateButtonSizer(flags) | |
685 | method that can be used to create a standard button sizer in which | |
686 | standard buttons are displayed. The following flags can be passed to | |
687 | this method: | |
688 | ||
689 | ============= ======================================================= | |
690 | wx.YES_NO add Yes/No subpanel | |
691 | wx.YES return wx.ID_YES | |
692 | wx.NO return wx.ID_NO | |
693 | wx.NO_DEFAULT make the wx.NO button the default, otherwise wx.YES or | |
694 | wx.OK button will be default | |
695 | wx.OK return wx.ID_OK | |
696 | wx.CANCEL return wx.ID_CANCEL | |
697 | wx.HELP return wx.ID_HELP | |
698 | wx.FORWARD return wx.ID_FORWARD | |
699 | wx.BACKWARD return wx.ID_BACKWARD | |
700 | wx.SETUP return wx.ID_SETUP | |
701 | wx.MORE return wx.ID_MORE | |
702 | ============= ======================================================= | |
703 | ||
704 | ||
705 | Date and time classes overview | |
706 | ============================== | |
707 | ||
708 | wxPython provides a set of powerful classes to work with dates and | |
709 | times. Some of the supported features of the DateTime class are: | |
710 | ||
711 | ============= ======================================================= | |
712 | ||
713 | Wide range The range of supported dates goes from about 4714 B.C. to | |
714 | some 480 million years in the future. | |
715 | ||
716 | Precision Not using floating point calculations anywhere ensures that | |
717 | the date calculations don't suffer from rounding | |
718 | errors. | |
719 | ||
720 | Many features Not only all usual calculations with dates are | |
721 | supported, but also more exotic week and year day | |
722 | calculations, work day testing, standard astronomical | |
723 | functions, conversion to and from strings in either | |
724 | strict or free format. | |
725 | ||
726 | ||
727 | Efficiency Objects of DateTime are small (8 bytes) and working | |
728 | with them is fast | |
729 | ||
730 | ============= ======================================================= | |
731 | ||
732 | ||
733 | All date/time classes at a glance | |
734 | --------------------------------- | |
735 | ||
736 | There are 3 main classes: except DateTime itself which represents an | |
737 | absolute moment in time, there are also two classes - TimeSpan and | |
738 | DateSpan which represent the intervals of time. | |
739 | ||
740 | There are also helper classes which are used together with DateTime: | |
741 | DateTimeHolidayAuthority which is used to determine whether a given | |
742 | date is a holiday or not and DateTimeWorkDays which is a derivation of | |
743 | this class for which (only) Saturdays and Sundays are the holidays. | |
744 | See more about these classes in the discussion of the holidays. | |
745 | ||
746 | ||
747 | DateTime characteristics | |
748 | ------------------------ | |
749 | ||
750 | DateTime stores the time as a signed number of milliseconds since the | |
751 | Epoch which is fixed, by convention, to Jan 1, 1970 - however this is | |
752 | not visible to the class users (in particular, dates prior to the | |
753 | Epoch are handled just as well (or as bad) as the dates after it). | |
754 | But it does mean that the best resolution which can be achieved with | |
755 | this class is 1 millisecond. | |
756 | ||
757 | The size of DateTime object is 8 bytes because it is represented as a | |
758 | 64 bit integer. The resulting range of supported dates is thus | |
759 | approximatively 580 million years, but due to the current limitations | |
760 | in the Gregorian calendar support, only dates from Nov 24, 4714BC are | |
761 | supported (this is subject to change if there is sufficient interest | |
762 | in doing it). | |
763 | ||
764 | Finally, the internal representation is time zone independent (always | |
765 | in GMT) and the time zones only come into play when a date is broken | |
766 | into year/month/day components. See more about timezones below. | |
767 | ||
768 | Currently, the only supported calendar is Gregorian one (which is used | |
769 | even for the dates prior to the historic introduction of this calendar | |
770 | which was first done on Oct 15, 1582 but is, generally speaking, | |
771 | country, and even region, dependent). Future versions will probably | |
772 | have Julian calendar support as well and support for other calendars | |
773 | (Maya, Hebrew, Chinese...) is not ruled out. | |
774 | ||
775 | ||
776 | Difference between DateSpan and TimeSpan | |
777 | ---------------------------------------- | |
778 | ||
779 | While there is only one logical way to represent an absolute moment in | |
780 | the time (and hence only one DateTime class), there are at least two | |
781 | methods to describe a time interval. | |
782 | ||
783 | First, there is the direct and self-explaining way implemented by | |
784 | TimeSpan: it is just a difference in milliseconds between two moments | |
785 | in time. Adding or subtracting such an interval to DateTime is always | |
786 | well-defined and is a fast operation. | |
787 | ||
788 | But in daily life other, calendar-dependent time interval | |
789 | specifications are used. For example, 'one month later' is commonly | |
790 | used. However, it is clear that this is not the same as TimeSpan of | |
791 | 60*60*24*31 seconds because 'one month later' Feb 15 is Mar 15 and not | |
792 | Mar 17 or Mar 16 (depending on whether the year is leap or not). | |
793 | ||
794 | This is why there is another class for representing such intervals | |
795 | called DateSpan. It handles these sort of operations in the most | |
796 | natural way possible, but note that manipulating with intervals of | |
797 | this kind is not always well-defined. Consider, for example, Jan 31 + | |
798 | '1 month': this will give Feb 28 (or 29), i.e. the last day of | |
799 | February and not the non-existent Feb 31. Of course, this is what is | |
800 | usually wanted, but you still might be surprised to notice that now | |
801 | subtracting back the same interval from Feb 28 will result in Jan 28 | |
802 | and not Jan 31 we started with! | |
803 | ||
804 | So, unless you plan to implement some kind of natural language parsing | |
805 | in the program, you should probably use TimeSpan instead of DateSpan | |
806 | (which is also more efficient). However, DateSpan may be very useful | |
807 | in situations when you do need to understand what 'in a month' means | |
808 | (of course, it is just DateTime.Now() + DateSpan.Month()). | |
809 | ||
810 | ||
811 | Date arithmetics | |
812 | ---------------- | |
813 | ||
814 | Many different operations may be performed with the dates, however not | |
815 | all of them make sense. For example, multiplying a date by a number | |
816 | is an invalid operation, even though multiplying either of the time | |
817 | span classes by a number is perfectly valid. | |
818 | ||
819 | Here is what can be done: | |
820 | ||
821 | ============== ====================================================== | |
822 | ||
823 | Addition a TimeSpan or DateSpan can be added to DateTime resulting in | |
824 | a new DateTime object and also 2 objects of the same | |
825 | span class can be added together giving another object | |
826 | of the same class. | |
827 | ||
828 | ||
829 | Subtraction the same types of operations as above are allowed and, | |
830 | additionally, a difference between two DateTime | |
831 | objects can be taken and this will yield TimeSpan. | |
832 | ||
833 | Multiplication a TimeSpan or DateSpan object can be multiplied by an | |
834 | integer number resulting in an object of the same | |
835 | type. | |
836 | ||
837 | ||
838 | Unary minus a TimeSpan or DateSpan object may finally be negated | |
839 | giving an interval of the same magnitude but of | |
840 | opposite time direction. | |
841 | ||
842 | ============== ====================================================== | |
843 | ||
844 | ||
845 | Time zone considerations | |
846 | ------------------------ | |
847 | ||
848 | Although the time is always stored internally in GMT, you will usually | |
849 | work in the local time zone. Because of this, all DateTime | |
850 | constructors and setters which take the broken down date assume that | |
851 | these values are for the local time zone. Thus, DateTime(1, | |
852 | DateTime.Jan, 1970) will not correspond to the DateTime Epoch unless | |
853 | you happen to live in the UK. | |
854 | ||
855 | All methods returning the date components (year, month, day, hour, | |
856 | minute, second...) will also return the correct values for the local | |
857 | time zone by default. So, generally, doing the natural things will | |
858 | lead to natural and correct results. | |
859 | ||
860 | If you only want to do this, you may safely skip the rest of this | |
861 | section. However, if you want to work with different time zones, you | |
862 | should read it to the end. | |
863 | ||
864 | In this (rare) case, you are still limited to the local time zone when | |
865 | constructing DateTime objects, i.e. there is no way to construct a | |
866 | DateTime corresponding to the given date in, say, Pacific Standard | |
867 | Time. To do it, you will need to call ToTimezone or MakeTimezone | |
868 | methods to adjust the date for the target time zone. There are also | |
869 | special versions of these functions ToGMT and MakeGMT for the most | |
870 | common case - when the date should be constructed in GMT. | |
871 | ||
872 | You also can just retrieve the value for some time zone without | |
873 | converting the object to it first. For this you may pass TimeZone | |
874 | argument to any of the methods which are affected by the time zone | |
875 | (all methods getting date components and the date formatting ones, for | |
876 | example). In particular, the Format() family of methods accepts a | |
877 | TimeZone parameter and this allows to simply print time in any time | |
878 | zone. | |
879 | ||
880 | To see how to do it, the last issue to address is how to construct a | |
881 | TimeZone object which must be passed to all these methods. First of | |
882 | all, you may construct it manually by specifying the time zone offset | |
883 | in seconds from GMT, but usually you will just use one of the symbolic | |
884 | time zone names and let the conversion constructor do the | |
885 | job. I.e. you would just write | |
886 | ||
887 | wxDateTime dt(...whatever...); | |
888 | printf("The time is %s in local time zone", dt.FormatTime().c_str()); | |
889 | printf("The time is %s in GMT", dt.FormatTime(wxDateTime::GMT).c_str()); | |
890 | ||
891 | ||
892 | Daylight saving time (DST) | |
893 | -------------------------- | |
894 | ||
895 | DST (a.k.a. 'summer time') handling is always a delicate task which is | |
896 | better left to the operating system which is supposed to be configured | |
897 | by the administrator to behave correctly. Unfortunately, when doing | |
898 | calculations with date outside of the range supported by the standard | |
899 | library, we are forced to deal with these issues ourselves. | |
900 | ||
901 | Several functions are provided to calculate the beginning and end of | |
902 | DST in the given year and to determine whether it is in effect at the | |
903 | given moment or not, but they should not be considered as absolutely | |
904 | correct because, first of all, they only work more or less correctly | |
905 | for only a handful of countries (any information about other ones | |
906 | appreciated!) and even for them the rules may perfectly well change in | |
907 | the future. | |
908 | ||
909 | The time zone handling methods use these functions too, so they are | |
910 | subject to the same limitations. | |
911 | ||
912 | ||
913 | DateTime and Holidays | |
914 | --------------------- | |
915 | ||
916 | [TODO] | |
917 | ||
918 | ||
919 | Classes by category | |
920 | =================== | |
921 | ||
922 | Not done yet. | |
923 | ||
924 | ||
925 | ID constants | |
926 | ============ | |
927 | ||
928 | wxPython provides the following predefined ID constants: | |
929 | ||
930 | ID_ABORT | |
931 | ID_ABOUT | |
932 | ID_ANY | |
933 | ID_APPLY | |
934 | ID_BACKWARD | |
935 | ID_CANCEL | |
936 | ID_CLEAR | |
937 | ID_CLOSE | |
938 | ID_CLOSE_ALL | |
939 | ID_CONTEXT_HELP | |
940 | ID_COPY | |
941 | ID_CUT | |
942 | ID_DEFAULT | |
943 | ID_DUPLICATE | |
944 | ID_EXIT | |
945 | ID_FILE1 | |
946 | ID_FILE2 | |
947 | ID_FILE3 | |
948 | ID_FILE4 | |
949 | ID_FILE5 | |
950 | ID_FILE6 | |
951 | ID_FILE7 | |
952 | ID_FILE8 | |
953 | ID_FILE9 | |
954 | ID_FILTERLISTCTRL | |
955 | ID_FIND | |
956 | ID_FORWARD | |
957 | ID_HELP | |
958 | ID_HELP_COMMANDS | |
959 | ID_HELP_CONTENTS | |
960 | ID_HELP_CONTEXT | |
961 | ID_HELP_PROCEDURES | |
962 | ID_IGNORE | |
963 | ID_MORE | |
964 | ID_NEW | |
965 | ID_NO | |
966 | ID_NOTOALL | |
967 | ID_OK | |
968 | ID_OPEN | |
969 | ID_PASTE | |
970 | ID_PREVIEW | |
971 | ID_PRINT | |
972 | ID_PRINT_SETUP | |
973 | ID_REDO | |
974 | ID_RESET | |
975 | ID_RETRY | |
976 | ID_REVERT | |
977 | ID_SAVE | |
978 | ID_SAVEAS | |
979 | ID_SELECTALL | |
980 | ID_SEPARATOR | |
981 | ID_SETUP | |
982 | ID_STATIC | |
983 | ID_TREECTRL | |
984 | ID_UNDO | |
985 | ID_YES | |
986 | ID_YESTOALL | |
987 | ||
988 | ||
989 | Source document | |
990 | =============== | |
991 | ||
992 | The source document is named wxPythonManual.txt and can be found by | |
993 | clicking the link at the bottom of this page (assuming you are viewing | |
994 | the html file). It is written using a fantastic formatting convention | |
995 | called reStructuredText. The wxPythonManual.html file is created | |
996 | using the Docutils utilities, which can turn reStructuredText | |
997 | documents into html, xml, pdf, and even OpenOffice files. | |
998 | ||
999 | ||
1000 | Submitting changes to the source document | |
1001 | ========================================= | |
1002 | ||
1003 | Some items in the source text file look like this:: | |
1004 | ||
1005 | .. This is text from the wxWidgets documentation that needs to be | |
1006 | translated into something appropriate for the wxPython version. | |
1007 | The two dots followed by uniformly indented text turns this | |
1008 | paragraph into a reStructuredText comment, so it doesn't appear | |
1009 | in any output file, such as the html file. | |
1010 | ||
1011 | They have been commented out and are awaiting editorial review and a | |
1012 | rewrite so that they make sense in the context of wxPython. Feel free | |
1013 | to send me suggestions for rewording these, or any other parts of this | |
1014 | document that you think need improving. I will be eternally grateful | |
1015 | to you and will show my gratitude by adding your name to the list of | |
1016 | contributors. (Contributors who also send me gifts of coffee, | |
1017 | chocolate, or currency will have their names listed in bold.) | |
1018 | ||
1019 | ||
1020 | Contributors | |
1021 | ============ | |
1022 | ||
1023 | Individuals who contributed to this documentation (in order by last | |
1024 | name): | |
1025 | ||
1026 | * Robin Dunn | |
1027 | * Patrick K. O'Brien | |
1028 | * Robert Roebling | |
1029 | * Julian Smart | |
1030 | * Vadim Zeitlin | |
1031 | ||
1032 | ||
1033 | License | |
1034 | ======= | |
1035 | ||
1036 | This document began as a translation of the wxWidgets documentation. | |
1037 | As such, it adheres to the same license, which is provided here: | |
1038 | ||
1039 | .. include:: ../licence/licendoc.txt | |
1040 | :literal: |