| 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: |