| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: python.h |
| 3 | // Purpose: topic overview |
| 4 | // Author: wxWidgets team |
| 5 | // RCS-ID: $Id$ |
| 6 | // Licence: wxWindows license |
| 7 | ///////////////////////////////////////////////////////////////////////////// |
| 8 | |
| 9 | /** |
| 10 | |
| 11 | @page overview_python wxPython Overview |
| 12 | |
| 13 | This topic was written by Robin Dunn, author of the |
| 14 | <a href="http://www.python.org/">wxPython</a> wrapper. |
| 15 | |
| 16 | @li @ref overview_python_what |
| 17 | @li @ref overview_python_why |
| 18 | @li @ref overview_python_othergui |
| 19 | @li @ref overview_python_using |
| 20 | @li @ref overview_python_classes |
| 21 | @li @ref overview_python_help |
| 22 | |
| 23 | |
| 24 | <hr> |
| 25 | |
| 26 | |
| 27 | @section overview_python_what What is wxPython? |
| 28 | |
| 29 | wxPython is a blending of the wxWidgets GUI classes and the Python programming |
| 30 | language. |
| 31 | |
| 32 | @subsection overview_python_what_py Python |
| 33 | |
| 34 | So what is Python? Go to http://www.python.org to learn more, but in a |
| 35 | nutshell Python is an interpreted, interactive, object-oriented programming |
| 36 | language. It is often compared to Tcl, Perl, Scheme or Java. |
| 37 | |
| 38 | Python combines remarkable power with very clear syntax. It has modules, |
| 39 | classes, exceptions, very high level dynamic data types, and dynamic typing. |
| 40 | There are interfaces to many system calls and libraries, and new built-in |
| 41 | modules are easily written in C or C++. Python is also usable as an extension |
| 42 | language for applications that need a programmable interface. |
| 43 | |
| 44 | Python is copyrighted but freely usable and distributable, even for commercial |
| 45 | use. |
| 46 | |
| 47 | @subsection overview_python_what_wxpy wxPython |
| 48 | |
| 49 | wxPython is a Python package that can be imported at runtime that includes a |
| 50 | collection of Python modules and an extension module (native code). It provides |
| 51 | a series of Python classes that mirror (or shadow) many of the wxWidgets GUI |
| 52 | classes. This extension module attempts to mirror the class hierarchy of |
| 53 | wxWidgets as closely as possible. This means that there is a wxFrame class in |
| 54 | wxPython that looks, smells, tastes and acts almost the same as the wxFrame |
| 55 | class in the C++ version. |
| 56 | |
| 57 | wxPython is very versatile. It can be used to create standalone GUI |
| 58 | applications, or in situations where Python is embedded in a C++ application as |
| 59 | an internal scripting or macro language. |
| 60 | |
| 61 | Currently wxPython is available for Win32 platforms and the GTK toolkit (wxGTK) |
| 62 | on most Unix/X-windows platforms. See the wxPython website http://wxPython.org/ |
| 63 | for details about getting wxPython working for you. |
| 64 | |
| 65 | |
| 66 | @section overview_python_why Why Use wxPython? |
| 67 | |
| 68 | So why would you want to use wxPython over just C++ and wxWidgets? Personally I |
| 69 | prefer using Python for everything. I only use C++ when I absolutely have to |
| 70 | eke more performance out of an algorithm, and even then I usually code it as an |
| 71 | extension module and leave the majority of the program in Python. |
| 72 | |
| 73 | Another good thing to use wxPython for is quick prototyping of your wxWidgets |
| 74 | apps. With C++ you have to continuously go though the edit-compile-link-run |
| 75 | cycle, which can be quite time consuming. With Python it is only an edit-run |
| 76 | cycle. You can easily build an application in a few hours with Python that |
| 77 | would normally take a few days or longer with C++. Converting a wxPython app to |
| 78 | a C++/wxWidgets app should be a straight forward task. |
| 79 | |
| 80 | |
| 81 | @section overview_python_othergui Other Python GUIs |
| 82 | |
| 83 | There are other GUI solutions out there for Python. |
| 84 | |
| 85 | @subsection overview_python_othergui_tkinter Tkinter |
| 86 | |
| 87 | Tkinter is the de facto standard GUI for Python. It is available on nearly |
| 88 | every platform that Python and Tcl/TK are. Why Tcl/Tk? Well because Tkinter is |
| 89 | just a wrapper around Tcl's GUI toolkit, Tk. This has it's upsides and it's |
| 90 | downsides... |
| 91 | |
| 92 | The upside is that Tk is a pretty versatile toolkit. It can be made to do a lot |
| 93 | of things in a lot of different environments. It is fairly easy to create new |
| 94 | widgets and use them interchangeably in your programs. |
| 95 | |
| 96 | The downside is Tcl. When using Tkinter you actually have two separate language |
| 97 | interpreters running, the Python interpreter and the Tcl interpreter for the |
| 98 | GUI. Since the guts of Tcl is mostly about string processing, it is fairly slow |
| 99 | as well. (Not too bad on a fast Pentium II, but you really notice the |
| 100 | difference on slower machines.) |
| 101 | |
| 102 | It wasn't until the latest version of Tcl/Tk that native Look and Feel was |
| 103 | possible on non-Motif platforms. This is because Tk usually implements its own |
| 104 | widgets (controls) even when there are native controls available. |
| 105 | |
| 106 | Tkinter is a pretty low-level toolkit. You have to do a lot of work (verbose |
| 107 | program code) to do things that would be much simpler with a higher level of |
| 108 | abstraction. |
| 109 | |
| 110 | @subsection overview_python_othergui_pythonwin PythonWin |
| 111 | |
| 112 | PythonWin is an add-on package for Python for the Win32 platform. It includes |
| 113 | wrappers for MFC as well as much of the Win32 API. Because of its foundation, |
| 114 | it is very familiar for programmers who have experience with MFC and the Win32 |
| 115 | API. It is obviously not compatible with other platforms and toolkits. |
| 116 | PythonWin is organized as separate packages and modules so you can use the |
| 117 | pieces you need without having to use the GUI portions. |
| 118 | |
| 119 | @subsection overview_python_othergui_others Others |
| 120 | |
| 121 | There are quite a few other GUI modules available for Python, some in active |
| 122 | use, some that haven't been updated for ages. Most are simple wrappers around |
| 123 | some C or C++ toolkit or another, and most are not cross-platform compatible. |
| 124 | See <a href="http://pypi.python.org/pypi?:action=browse&show=all&c=433">this link</a> |
| 125 | for a listing of a few of them. |
| 126 | |
| 127 | |
| 128 | @section overview_python_using Using wxPython |
| 129 | |
| 130 | I'm not going to try and teach the Python language here. You can do that at the |
| 131 | <a href="http://www.python.org/doc/tut/tut.html">Python Tutorial</a>. I'm also |
| 132 | going to assume that you know a bit about wxWidgets already, enough to notice |
| 133 | the similarities in the classes used. |
| 134 | |
| 135 | Take a look at the following wxPython program. You can find a similar program |
| 136 | in the @c wxPython/demo directory, named @c DialogUnits.py. If your Python and |
| 137 | wxPython are properly installed, you should be able to run it by issuing this |
| 138 | command: |
| 139 | |
| 140 | @code |
| 141 | python DialogUnits.py |
| 142 | @endcode |
| 143 | |
| 144 | @code |
| 145 | 01: ## import all of the wxPython GUI package |
| 146 | 02: from wxPython.wx import * |
| 147 | 03: |
| 148 | 04: ## Create a new frame class, derived from the wxPython Frame. |
| 149 | 05: class MyFrame(wxFrame): |
| 150 | 06: |
| 151 | 07: def __init__(self, parent, id, title): |
| 152 | 08: # First, call the base class' __init__ method to create the frame |
| 153 | 09: wxFrame.__init__(self, parent, id, title, |
| 154 | 10: wxPoint(100, 100), wxSize(160, 100)) |
| 155 | 11: |
| 156 | 12: # Associate some events with methods of this class |
| 157 | 13: EVT_SIZE(self, self.OnSize) |
| 158 | 14: EVT_MOVE(self, self.OnMove) |
| 159 | 15: |
| 160 | 16: # Add a panel and some controls to display the size and position |
| 161 | 17: panel = wxPanel(self, -1) |
| 162 | 18: wxStaticText(panel, -1, "Size:", |
| 163 | 19: wxDLG_PNT(panel, wxPoint(4, 4)), wxDefaultSize) |
| 164 | 20: wxStaticText(panel, -1, "Pos:", |
| 165 | 21: wxDLG_PNT(panel, wxPoint(4, 14)), wxDefaultSize) |
| 166 | 22: self.sizeCtrl = wxTextCtrl(panel, -1, "", |
| 167 | 23: wxDLG_PNT(panel, wxPoint(24, 4)), |
| 168 | 24: wxDLG_SZE(panel, wxSize(36, -1)), |
| 169 | 25: wxTE_READONLY) |
| 170 | 26: self.posCtrl = wxTextCtrl(panel, -1, "", |
| 171 | 27: wxDLG_PNT(panel, wxPoint(24, 14)), |
| 172 | 28: wxDLG_SZE(panel, wxSize(36, -1)), |
| 173 | 29: wxTE_READONLY) |
| 174 | 30: |
| 175 | 31: |
| 176 | 32: # This method is called automatically when the CLOSE event is |
| 177 | 33: # sent to this window |
| 178 | 34: def OnCloseWindow(self, event): |
| 179 | 35: # tell the window to kill itself |
| 180 | 36: self.Destroy() |
| 181 | 37: |
| 182 | 38: # This method is called by the system when the window is resized, |
| 183 | 39: # because of the association above. |
| 184 | 40: def OnSize(self, event): |
| 185 | 41: size = event.GetSize() |
| 186 | 42: self.sizeCtrl.SetValue("%s, %s" % (size.width, size.height)) |
| 187 | 43: |
| 188 | 44: # tell the event system to continue looking for an event handler, |
| 189 | 45: # so the default handler will get called. |
| 190 | 46: event.Skip() |
| 191 | 47: |
| 192 | 48: # This method is called by the system when the window is moved, |
| 193 | 49: # because of the association above. |
| 194 | 50: def OnMove(self, event): |
| 195 | 51: pos = event.GetPosition() |
| 196 | 52: self.posCtrl.SetValue("%s, %s" % (pos.x, pos.y)) |
| 197 | 53: |
| 198 | 54: |
| 199 | 55: # Every wxWidgets application must have a class derived from wxApp |
| 200 | 56: class MyApp(wxApp): |
| 201 | 57: |
| 202 | 58: # wxWidgets calls this method to initialize the application |
| 203 | 59: def OnInit(self): |
| 204 | 60: |
| 205 | 61: # Create an instance of our customized Frame class |
| 206 | 62: frame = MyFrame(NULL, -1, "This is a test") |
| 207 | 63: frame.Show(true) |
| 208 | 64: |
| 209 | 65: # Tell wxWidgets that this is our main window |
| 210 | 66: self.SetTopWindow(frame) |
| 211 | 67: |
| 212 | 68: # Return a success flag |
| 213 | 69: return true |
| 214 | 70: |
| 215 | 71: |
| 216 | 72: app = MyApp(0) # Create an instance of the application class |
| 217 | 73: app.MainLoop() # Tell it to start processing events |
| 218 | 74: |
| 219 | @endcode |
| 220 | |
| 221 | @subsection overview_python_using_notice Things to Notice |
| 222 | |
| 223 | At line 2 the wxPython classes, constants, and etc. are imported into the |
| 224 | current module's namespace. If you prefer to reduce namespace pollution you can |
| 225 | use @c "from wxPython import wx" and then access all the wxPython identifiers |
| 226 | through the wx module, for example, @c "wx.wxFrame". |
| 227 | |
| 228 | At line 13 the frame's sizing and moving events are connected to methods of the |
| 229 | class. These helper functions are intended to be like the event table macros |
| 230 | that wxWidgets employs. But since static event tables are impossible with |
| 231 | wxPython, we use helpers that are named the same to dynamically build the |
| 232 | table. The only real difference is that the first argument to the event helpers |
| 233 | is always the window that the event table entry should be added to. |
| 234 | |
| 235 | Notice the use of @c wxDLG_PNT and @c wxDLG_SZE in lines 19-29 to convert from |
| 236 | dialog units to pixels. These helpers are unique to wxPython since Python can't |
| 237 | do method overloading like C++. |
| 238 | |
| 239 | There is an @c OnCloseWindow method at line 34 but no call to @c EVT_CLOSE to |
| 240 | attach the event to the method. Does it really get called? The answer is, yes |
| 241 | it does. This is because many of the standard events are attached to windows |
| 242 | that have the associated standard method names. I have tried to follow the lead |
| 243 | of the C++ classes in this area to determine what is standard but since that |
| 244 | changes from time to time I can make no guarantees, nor will it be fully |
| 245 | documented. When in doubt, use an @c EVT_*** function. |
| 246 | |
| 247 | At lines 17 to 21 notice that there are no saved references to the panel or the |
| 248 | static text items that are created. Those of you who know Python might be |
| 249 | wondering what happens when Python deletes these objects when they go out of |
| 250 | scope. Do they disappear from the GUI? They don't. Remember that in wxPython |
| 251 | the Python objects are just shadows of the corresponding C++ objects. Once the |
| 252 | C++ windows and controls are attached to their parents, the parents manage them |
| 253 | and delete them when necessary. For this reason, most wxPython objects do not |
| 254 | need to have a @c __del__ method that explicitly causes the C++ object to be |
| 255 | deleted. If you ever have the need to forcibly delete a window, use the |
| 256 | Destroy() method as shown on line 36. |
| 257 | |
| 258 | Just like wxWidgets in C++, wxPython apps need to create a class derived from |
| 259 | @c wxApp (line 56) that implements a method named @c OnInit, (line 59.) This |
| 260 | method should create the application's main window (line 62) and use |
| 261 | wxApp.SetTopWindow() (line 66) to inform wxWidgets about it. |
| 262 | |
| 263 | And finally, at line 72 an instance of the application class is created. At |
| 264 | this point wxPython finishes initializing itself, and calls the @c OnInit |
| 265 | method to get things started. (The zero parameter here is a flag for |
| 266 | functionality that isn't quite implemented yet. Just ignore it for now.) The |
| 267 | call to @c MainLoop at line 73 starts the event loop which continues until the |
| 268 | application terminates or all the top level windows are closed. |
| 269 | |
| 270 | |
| 271 | @section overview_python_classes Classes Implemented in wxPython |
| 272 | |
| 273 | The following classes are supported in wxPython. Most provide nearly full |
| 274 | implementations of the public interfaces specified in the C++ documentation, |
| 275 | others are less so. They will all be brought as close as possible to the C++ |
| 276 | spec over time. |
| 277 | |
| 278 | @li wxAcceleratorEntry |
| 279 | @li wxAcceleratorTable |
| 280 | @li wxActivateEvent |
| 281 | @li wxBitmap |
| 282 | @li wxBitmapButton |
| 283 | @li wxBitmapDataObject |
| 284 | @li wxBMPHandler |
| 285 | @li wxBoxSizer |
| 286 | @li wxBrush |
| 287 | @li wxBusyInfo |
| 288 | @li wxBusyCursor |
| 289 | @li wxButton |
| 290 | @li wxCalculateLayoutEvent |
| 291 | @li wxCalendarCtrl |
| 292 | @li wxCaret |
| 293 | @li wxCheckBox |
| 294 | @li wxCheckListBox |
| 295 | @li wxChoice |
| 296 | @li wxClientDC |
| 297 | @li wxClipboard |
| 298 | @li wxCloseEvent |
| 299 | @li wxColourData |
| 300 | @li wxColourDialog |
| 301 | @li wxColour |
| 302 | @li wxComboBox |
| 303 | @li wxCommandEvent |
| 304 | @li wxConfigBase |
| 305 | @li wxControl |
| 306 | @li wxCursor |
| 307 | @li wxCustomDataObject |
| 308 | @li wxDataFormat |
| 309 | @li wxDataObject |
| 310 | @li wxDataObjectComposite |
| 311 | @li wxDataObjectSimple |
| 312 | @li wxDateTime |
| 313 | @li wxDateSpan |
| 314 | @li wxDC |
| 315 | @li wxDialog |
| 316 | @li wxDirDialog |
| 317 | @li wxDragImage |
| 318 | @li wxDropFilesEvent |
| 319 | @li wxDropSource |
| 320 | @li wxDropTarget |
| 321 | @li wxEraseEvent |
| 322 | @li wxEvent |
| 323 | @li wxEvtHandler |
| 324 | @li wxFileConfig |
| 325 | @li wxFileDataObject |
| 326 | @li wxFileDialog |
| 327 | @li wxFileDropTarget |
| 328 | @li wxFileSystem |
| 329 | @li wxFileSystemHandler |
| 330 | @li wxFocusEvent |
| 331 | @li wxFontData |
| 332 | @li wxFontDialog |
| 333 | @li wxFont |
| 334 | @li wxFrame |
| 335 | @li wxFSFile |
| 336 | @li wxGauge |
| 337 | @li wxGIFHandler |
| 338 | @li wxGLCanvas |
| 339 | @li wxHtmlCell |
| 340 | @li wxHtmlContainerCell |
| 341 | @li wxHtmlDCRenderer |
| 342 | @li wxHtmlEasyPrinting |
| 343 | @li wxHtmlParser |
| 344 | @li wxHtmlTagHandler |
| 345 | @li wxHtmlTag |
| 346 | @li wxHtmlWinParser |
| 347 | @li wxHtmlPrintout |
| 348 | @li wxHtmlWinTagHandler |
| 349 | @li wxHtmlWindow |
| 350 | @li wxIconizeEvent |
| 351 | @li wxIcon |
| 352 | @li wxIdleEvent |
| 353 | @li wxImage |
| 354 | @li wxImageHandler |
| 355 | @li wxImageList |
| 356 | @li wxIndividualLayoutConstraint |
| 357 | @li wxInitDialogEvent |
| 358 | @li wxInputStream |
| 359 | @li @ref wxFileSystem "wxInternetFSHandler" |
| 360 | @li wxJoystickEvent |
| 361 | @li wxJPEGHandler |
| 362 | @li wxKeyEvent |
| 363 | @li wxLayoutAlgorithm |
| 364 | @li wxLayoutConstraints |
| 365 | @li wxListBox |
| 366 | @li wxListCtrl |
| 367 | @li wxListEvent |
| 368 | @li wxListItem |
| 369 | @li wxMask |
| 370 | @li wxMaximizeEvent |
| 371 | @li wxMDIChildFrame |
| 372 | @li wxMDIClientWindow |
| 373 | @li wxMDIParentFrame |
| 374 | @li wxMemoryDC |
| 375 | @li wxMemoryFSHandler |
| 376 | @li wxMenuBar |
| 377 | @li wxMenuEvent |
| 378 | @li wxMenuItem |
| 379 | @li wxMenu |
| 380 | @li wxMessageDialog |
| 381 | @li wxMetafileDC |
| 382 | @li wxMiniFrame |
| 383 | @li wxMouseEvent |
| 384 | @li wxMoveEvent |
| 385 | @li wxNotebookEvent |
| 386 | @li wxNotebook |
| 387 | @li wxPageSetupDialogData |
| 388 | @li wxPageSetupDialog |
| 389 | @li wxPaintDC |
| 390 | @li wxPaintEvent |
| 391 | @li wxPalette |
| 392 | @li wxPanel |
| 393 | @li wxPen |
| 394 | @li wxPNGHandler |
| 395 | @li wxPoint |
| 396 | @li wxPostScriptDC |
| 397 | @li wxPreviewFrame |
| 398 | @li wxPrintData |
| 399 | @li wxPrintDialogData |
| 400 | @li wxPrintDialog |
| 401 | @li wxPrinter |
| 402 | @li wxPrintPreview |
| 403 | @li wxPrinterDC |
| 404 | @li wxPrintout |
| 405 | @li wxProcess |
| 406 | @li wxQueryLayoutInfoEvent |
| 407 | @li wxRadioBox |
| 408 | @li wxRadioButton |
| 409 | @li wxRealPoint |
| 410 | @li wxRect |
| 411 | @li wxRegionIterator |
| 412 | @li wxRegion |
| 413 | @li wxSashEvent |
| 414 | @li wxSashLayoutWindow |
| 415 | @li wxSashWindow |
| 416 | @li wxScreenDC |
| 417 | @li wxScrollBar |
| 418 | @li wxScrollEvent |
| 419 | @li ::wxScrolledWindow |
| 420 | @li wxScrollWinEvent |
| 421 | @li wxShowEvent |
| 422 | @li wxSingleChoiceDialog |
| 423 | @li wxSizeEvent |
| 424 | @li wxSize |
| 425 | @li wxSizer |
| 426 | @li wxSizerItem |
| 427 | @li wxSlider |
| 428 | @li wxSpinButton |
| 429 | @li wxSpinEvent |
| 430 | @li wxSplitterWindow |
| 431 | @li wxStaticBitmap |
| 432 | @li wxStaticBox |
| 433 | @li wxStaticBoxSizer |
| 434 | @li wxStaticLine |
| 435 | @li wxStaticText |
| 436 | @li wxStatusBar |
| 437 | @li wxSysColourChangedEvent |
| 438 | @li wxTaskBarIcon |
| 439 | @li wxTextCtrl |
| 440 | @li wxTextDataObject |
| 441 | @li wxTextDropTarget |
| 442 | @li wxTextEntryDialog |
| 443 | @li wxTimer |
| 444 | @li wxTimerEvent |
| 445 | @li wxTimeSpan |
| 446 | @li wxTipProvider |
| 447 | @li wxToolBarTool |
| 448 | @li wxToolBar |
| 449 | @li wxToolTip |
| 450 | @li wxTreeCtrl |
| 451 | @li wxTreeEvent |
| 452 | @li wxTreeItemData |
| 453 | @li wxTreeItemId |
| 454 | @li wxUpdateUIEvent |
| 455 | @li wxValidator |
| 456 | @li wxWindowDC |
| 457 | @li wxWindow |
| 458 | @li @ref wxFileSystem "wxZipFSHandler" |
| 459 | |
| 460 | |
| 461 | @section overview_python_help Where to Go for Help |
| 462 | |
| 463 | Since wxPython is a blending of multiple technologies, help comes from multiple |
| 464 | sources. See http://wxpython.org/ for details on various sources of help, but |
| 465 | probably the best source is the wxPython-users mail list. You can view the |
| 466 | archive or subscribe by going to http://wxpython.org/maillist.php |
| 467 | |
| 468 | Or you can send mail directly to the list using this address: |
| 469 | wxpython-users@lists.wxwidgets.org |
| 470 | |
| 471 | */ |
| 472 | |