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