git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33791 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			981 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			981 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ============================
 | ||
| wxPython 2.6 Migration Guide
 | ||
| ============================
 | ||
| 
 | ||
| This document will help explain some of the major changes in wxPython
 | ||
| 2.6 since the 2.4 series and let you know what you need to do to adapt
 | ||
| your programs to those changes.  Be sure to also check in the CHANGES_
 | ||
| file like usual to see info about the not so major changes and other
 | ||
| things that have been added to wxPython.
 | ||
| 
 | ||
| .. _CHANGES: CHANGES.html
 | ||
| 
 | ||
| 
 | ||
| wxName Change
 | ||
| -------------
 | ||
| 
 | ||
| The **wxWindows** project and library is now known as
 | ||
| **wxWidgets**.  Please see here_ for more details.
 | ||
| 
 | ||
| .. _here: http://www.wxwidgets.org/name.htm
 | ||
| 
 | ||
| This won't really affect wxPython all that much, other than the fact
 | ||
| that the wxwindows.org domain name has changed to wxwidgets.org,
 | ||
| so mail list, CVS, and etc. addresses have also changed.  We're going
 | ||
| to try and smooth the transition as much as possible, but I wanted you
 | ||
| all to be aware of this change if you run into any issues.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Module Initialization
 | ||
| ---------------------
 | ||
| 
 | ||
| The import-startup-bootstrap process employed by wxPython was changed
 | ||
| such that wxWidgets and the underlying gui toolkit are **not**
 | ||
| initialized until the wx.App object is created (but before wx.App.OnInit
 | ||
| is called.)  This was required because of some changes that were made
 | ||
| to the C++ wxApp class.
 | ||
| 
 | ||
| There are both benefits and potential problems with this change.  The
 | ||
| benefits are that you can import wxPython without requiring access to
 | ||
| a GUI (for checking version numbers, etc.) and that in a
 | ||
| multi-threaded environment the thread that creates the app object will
 | ||
| now be the GUI thread instead of the one that imports wxPython.  Some
 | ||
| potential problems are that the C++ side of the "stock-objects"
 | ||
| (wx.BLUE_PEN, wx.TheColourDatabase, etc.) are not initialized until
 | ||
| the wx.App object is created, so you should not use them until after
 | ||
| you have created your wx.App object.  If you do then an exception will
 | ||
| be raised telling you that the C++ object has not been initialized
 | ||
| yet.
 | ||
| 
 | ||
| Also, you will probably not be able to do any kind of GUI or bitmap
 | ||
| operation unless you first have created an app object, (even on
 | ||
| Windows where most anything was possible before.)
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** All the Window and GDI (pen, bitmap, etc.)
 | ||
| class constructors and also many toplevel functions and static methods
 | ||
| will now check that a wx.App object has already been created and will
 | ||
| raise a wx.PyNoAppError exception if not.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| SWIG 1.3
 | ||
| --------
 | ||
| 
 | ||
| wxPython is now using SWIG 1.3.x from CVS (with several of my own
 | ||
| customizations added that I hope to get folded back into the main SWIG
 | ||
| distribution.)  This has some far reaching ramifications:
 | ||
| 
 | ||
|     All classes derive from object and so all are now "new-style
 | ||
|     classes."  This also allows you to use mixin classes that are
 | ||
|     new-style and to use properties, staticmethod, etc.
 | ||
| 
 | ||
|     Public data members of the C++ classes are wrapped as Python
 | ||
|     properties using property() instead of using
 | ||
|     __getattr__/__setattr__ hacks like before.  Normally you shouldn't
 | ||
|     notice any difference, but if you were previously doing something
 | ||
|     with __getattr__/__setattr__ in derived classes then you may have
 | ||
|     to adjust things.
 | ||
| 
 | ||
|     Static C++ methods are wrapped using the staticmethod() feature of
 | ||
|     Python and so are accessible as ClassName.MethodName as expected.
 | ||
|     They are still also available as top level functions named like
 | ||
|     ClassName_MethodName as before.
 | ||
| 
 | ||
|     The relationship between the wxFoo and wxFooPtr classes have
 | ||
|     changed for the better.  Specifically, all instances that you see
 | ||
|     will be wx.Foo even if they are created internally using wx.FooPtr,
 | ||
|     because wx.FooPtr.__init__ will change the instance's __class__ as
 | ||
|     part of the initialization.  If you have any code that checks
 | ||
|     class type using something like isinstance(obj, wx.FooPtr) you will
 | ||
|     need to change it to isinstance(obj, wx.Foo).
 | ||
| 
 | ||
|     
 | ||
| 
 | ||
| Binding Events
 | ||
| --------------
 | ||
| 
 | ||
| All of the EVT_* functions are now instances of the wx.PyEventBinder
 | ||
| class.  They have a __call__ method so they can still be used as
 | ||
| functions like before, but making them instances adds some
 | ||
| flexibility that I expect to take advantave of in the future.
 | ||
| 
 | ||
| wx.EvtHandler (the base class for wx.Window) now has a Bind method that
 | ||
| makes binding events to windows a little easier.  Here is its
 | ||
| definition and docstring::
 | ||
| 
 | ||
|         def Bind(self, event, handler, source=None, id=wxID_ANY, id2=wxID_ANY):
 | ||
|             """
 | ||
|             Bind an event to an event handler.
 | ||
| 
 | ||
|               event     One of the EVT_* objects that specifies the
 | ||
|                         type of event to bind.
 | ||
| 
 | ||
|               handler   A callable object to be invoked when the event
 | ||
|                         is delivered to self.  Pass None to disconnect an
 | ||
|                         event handler.
 | ||
| 
 | ||
|               source    Sometimes the event originates from a different window
 | ||
|                         than self, but you still want to catch it in self.  (For
 | ||
|                         example, a button event delivered to a frame.)  By
 | ||
|                         passing the source of the event, the event handling
 | ||
|                         system is able to differentiate between the same event
 | ||
|                         type from different controls.
 | ||
| 
 | ||
|               id,id2    Used for menu IDs or for event types that require a
 | ||
|                         range of IDs
 | ||
| 
 | ||
|             """
 | ||
| 
 | ||
| Some examples of its use::
 | ||
| 
 | ||
|      self.Bind(wx.EVT_SIZE,   self.OnSize)
 | ||
|      self.Bind(wx.EVT_BUTTON, self.OnButtonClick, theButton)
 | ||
|      self.Bind(wx.EVT_MENU,   self.OnExit, id=wx.ID_EXIT)
 | ||
| 
 | ||
| 
 | ||
| The wx.Menu methods that add items to a wx.Menu have been modified
 | ||
| such that they return a reference to the wx.MenuItem that was created.
 | ||
| Additionally menu items and toolbar items have been modified to
 | ||
| automatically generate a new ID if -1 is given, similar to using -1
 | ||
| with window classess.  This means that you can create menu or toolbar
 | ||
| items and event bindings without having to predefine a unique menu ID,
 | ||
| although you still can use IDs just like before if you want.  For
 | ||
| example, these are all equivallent other than their specific ID
 | ||
| values::
 | ||
| 
 | ||
|   1.
 | ||
|     item = menu.Append(-1, "E&xit", "Terminate the App")
 | ||
|     self.Bind(wx.EVT_MENU, self.OnExit, item)
 | ||
| 
 | ||
|   2. 
 | ||
|     item = menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App")
 | ||
|     self.Bind(wx.EVT_MENU, self.OnExit, item)
 | ||
| 
 | ||
|   3. 
 | ||
|     menu.Append(wx.ID_EXIT, "E&xit", "Terminate the App")
 | ||
|     self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
 | ||
| 
 | ||
|      
 | ||
| If you create your own custom event types and EVT_* functions, and you
 | ||
| want to be able to use them with the Bind method above then you should
 | ||
| change your EVT_* to be an instance of wx.PyEventBinder instead of a
 | ||
| function.  For example, if you used to have something like this::
 | ||
| 
 | ||
|     myCustomEventType = wxNewEventType()
 | ||
|     def EVT_MY_CUSTOM_EVENT(win, id, func):
 | ||
|         win.Connect(id, -1, myCustomEventType, func)
 | ||
| 
 | ||
| 
 | ||
| Change it like so::
 | ||
| 
 | ||
|     myCustomEventType = wx.NewEventType()
 | ||
|     EVT_MY_CUSTOM_EVENT = wx.PyEventBinder(myCustomEventType, 1)
 | ||
| 
 | ||
| The second parameter is an integer in [0, 1, 2] that specifies the
 | ||
| number of IDs that are needed to be passed to Connect.
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** There is also an Unbind method added to
 | ||
| wx.EvtHandler that can be used to disconenct event handlers.  It looks
 | ||
| like this::
 | ||
| 
 | ||
|     def Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
 | ||
|         """
 | ||
|         Disconencts the event handler binding for event from self.
 | ||
|         Returns True if successful.
 | ||
|         """
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| The wx Namespace
 | ||
| ----------------
 | ||
| 
 | ||
| The second phase of the wx Namespace Transition has begun.  That means
 | ||
| that the real names of the classes and other symbols do not have the
 | ||
| 'wx' prefix and the modules are located in a Python package named
 | ||
| wx.  There is still a Python package named wxPython with modules
 | ||
| that have the names with the wx prefix for backwards compatibility.
 | ||
| Instead of dynamically changing the names at module load time like in
 | ||
| 2.4, the compatibility modules are generated at build time and contain
 | ||
| assignment statements like this::
 | ||
| 
 | ||
|     wxWindow = wx._core.Window
 | ||
| 
 | ||
| Don't let the "_core" in the name bother you.  That and some other
 | ||
| modules are implementation details, and everything that was in the
 | ||
| wxPython.wx module before will still be in the wx package namespace
 | ||
| after this change.  So from your code you would use it as wx.Window or
 | ||
| wxWindow if you import from the wxPython.wx module.
 | ||
| 
 | ||
| A few notes about how all of this was accomplished might be
 | ||
| interesting...  SWIG is now run twice for each module that it is
 | ||
| generating code for.  The first time it outputs an XML representaion
 | ||
| of the parse tree, which can be up to 20MB and 300K lines in size!
 | ||
| That XML is then run through a little Python script that creates a
 | ||
| file full of SWIG %rename directives that take the wx off of the
 | ||
| names, and also generates the Python compatibility file described
 | ||
| above that puts the wx back on the names.  SWIG is then run a second
 | ||
| time to generate the C++ code to implement the extension module, and
 | ||
| uses the %rename directives that were generated in the first step.
 | ||
| 
 | ||
| Not every name is handled correctly (but the bulk of them are) and so
 | ||
| some work has to be done by hand, especially for the reverse-renamers.
 | ||
| So expect a few flaws here and there until everything gets sorted out.
 | ||
| 
 | ||
| In summary, the wx package and names without the "wx" prefix are now
 | ||
| the official form of the wxPython classes.  For example::
 | ||
| 
 | ||
|     import wx
 | ||
| 
 | ||
|     class MyFrame(wx.Frame):
 | ||
|         def __init__(self, parent, title):
 | ||
| 	    wx.Frame.__init__(self, parent, -1, title)
 | ||
| 	    p = wx.Panel(self, -1)
 | ||
| 	    b = wx.Button(p, -1, "Do It", (10,10))
 | ||
| 	    self.Bind(wx.EVT_BUTTON, self.JustDoIt, b)
 | ||
| 
 | ||
| 	def JustDoIt(self, evt):
 | ||
| 	    print "It's done!"
 | ||
| 
 | ||
|     app = wx.PySimpleApp()
 | ||
|     f = MyFrame(None, "What's up?")
 | ||
|     f.Show()
 | ||
|     app.MainLoop()
 | ||
| 
 | ||
| You shouldn't need to migrate all your modules over to use the new
 | ||
| package and names right away as there are modules in place that try to
 | ||
| provide as much backwards compatibility of the names as possible.  If
 | ||
| you rewrote the above sample using "from wxPython.wx import * ", the
 | ||
| old wxNames, and the old style of event binding it will still work
 | ||
| just fine.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| New wx.DC Methods
 | ||
| -----------------
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** In wxPython 2.5.1.5 there was a new
 | ||
| implementation of the wx.DC Draw and other methods that broke
 | ||
| backwards compatibility in the name of consistency.  That change has
 | ||
| been reverted and the wx.DC Draw methods with 2.4 compatible
 | ||
| signatures have been restored.  In addition a new set of methods have
 | ||
| been added that take wx.Point and/or wx.Size parameters instead of
 | ||
| separate integer parameters.  The Draw and etc. methods now available
 | ||
| in the wx.DC class are::
 | ||
| 
 | ||
| 
 | ||
|     FloodFill(self, x, y, colour, style = wx.FLOOD_SURFACE)
 | ||
|     FoodFillPoint(self, pt, colour, style = wx.FLOOD_SURFACE)
 | ||
| 
 | ||
|     GetPixel(self, x,y)
 | ||
|     GetPixelPoint(self, pt) 
 | ||
|     
 | ||
|     DrawLine(self, x1, y1, x2, y2)
 | ||
|     DrawLinePoint(self, pt1, pt2)
 | ||
| 
 | ||
|     CrossHair(self, x, y)
 | ||
|     CrossHairPoint(self, pt)
 | ||
| 
 | ||
|     DrawArc(self, x1, y1, x2, y2, xc, yc)
 | ||
|     DrawArcPoint(self, pt1, pt2, centre)
 | ||
| 
 | ||
|     DrawCheckMark(self, x, y, width, height)
 | ||
|     DrawCheckMarkRect(self, rect)
 | ||
| 
 | ||
|     DrawEllipticArc(self, x, y, w, h, sa, ea)
 | ||
|     DrawEllipticArcPointSize(self, pt, sz, sa, ea)
 | ||
| 
 | ||
|     DrawPoint(self, x, y)
 | ||
|     DrawPointPoint(self, pt)
 | ||
| 
 | ||
|     DrawRectangle(self, x, y, width, height)
 | ||
|     DrawRectangleRect(self, rect)
 | ||
|     DrawRectanglePointSize(self, pt, sz)
 | ||
| 
 | ||
|     DrawRoundedRectangle(self, x, y, width, height, radius)
 | ||
|     DrawRoundedRectangleRect(self, r, radius)
 | ||
|     DrawRoundedRectanglePointSize(self, pt, sz, radius)
 | ||
| 
 | ||
|     DrawCircle(self, x, y, radius)
 | ||
|     DrawCirclePoint(self, pt, radius)
 | ||
| 
 | ||
|     DrawEllipse(self, x, y, width, height)
 | ||
|     DrawEllipseRect(self, rect)
 | ||
|     DrawEllipsePointSize(self, pt, sz)
 | ||
| 
 | ||
|     DrawIcon(self, icon, x, y)
 | ||
|     DrawIconPoint(self, icon, pt)
 | ||
| 
 | ||
|     DrawBitmap(self, bmp, x, y, useMask = False)
 | ||
|     DrawBitmapPoint(self, bmp, pt, useMask = False)
 | ||
| 
 | ||
|     DrawText(self, text, x, y)
 | ||
|     DrawTextPoint(self, text, pt)
 | ||
| 
 | ||
|     DrawRotatedText(self, text, x, y, angle)
 | ||
|     DrawRotatedTextPoint(self, text, pt, angle)
 | ||
| 
 | ||
|     bool Blit(self, xdest, ydest, width, height, sourceDC, xsrc, ysrc,
 | ||
|               rop = wx.COPY, useMask = False, xsrcMask = -1, ysrcMask = -1)
 | ||
|     BlitPointSize(self, destPt, sz, sourceDC, srcPt, rop = wx.COPY, 
 | ||
|                   useMask = False, srcPtMask = wxDefaultPosition)
 | ||
| 
 | ||
| 
 | ||
|     SetClippingRegion(self, x, y, width, height)
 | ||
|     SetClippingRegionPointSize(self, pt, sz)
 | ||
|     SetClippingRegionAsRegion(self, region)
 | ||
|     SetClippingRect(self, rect)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Building, Extending and Embedding wxPython
 | ||
| ------------------------------------------
 | ||
| 
 | ||
| wxPython's setup.py script now expects to use existing libraries for
 | ||
| the contribs (gizmos, stc, xrc, etc.) rather than building local
 | ||
| copies of them.  If you build your own copies of wxPython please be
 | ||
| aware that you now need to also build the stc, xrc, animate and gizmos
 | ||
| libraries in addition to the main wx lib.
 | ||
| 
 | ||
| The wxPython.h and other header files are now in
 | ||
| .../wxPython/include/wx/wxPython instead of in wxPython/src.  You
 | ||
| should include it via the "wx/wxPython/wxPython.h" path and add
 | ||
| .../wxPython/include to your list of include paths.  On OSX and
 | ||
| unix-like systems the wxPython headers are installed to the same place
 | ||
| that the wxWidgets headers are installed, so if you are building
 | ||
| wxPython compatible extensions on those platforms then your include
 | ||
| path should already be set properly.
 | ||
| 
 | ||
| If you are also using SWIG for your extension then you'll need to
 | ||
| adapt how the wxPython .i files are imported into your .i files.  See
 | ||
| the wxPython sources for examples.  Your modules will need to at least
 | ||
| ``%import core.i``, and possibly others if you need the definition of
 | ||
| other classes.  Since you will need them to build your modules using
 | ||
| SWIG, the main wxPython .i files are also installed with the wxPython
 | ||
| headers in an i_files sibdirectory.  It should be enough to pass a
 | ||
| -I/pathname on the command line for SWIG to find the files.
 | ||
| 
 | ||
| The bulk of wxPython's setup.py has been moved to another module,
 | ||
| wx/build/config.py.  This module will be installed as part of wxPython
 | ||
| so 3rd party modules that wish to use the same setup/configuration
 | ||
| code can do so simply by importing this module from their own setup.py
 | ||
| scripts using ``import wx.build.config``. 
 | ||
| 
 | ||
| You no longer need to call wxClassInfo::CleanUpClasses() and
 | ||
| wxClassInfo::InitializeClasses() in your extensions or when embedding
 | ||
| wxPython. 
 | ||
| 
 | ||
| The usage of wxPyBeginAllowThreads and wxPyEndAllowThreads has changed
 | ||
| slightly.  wxPyBeginAllowThreads now returns a boolean value that must
 | ||
| be passed to the coresponding wxPyEndAllowThreads function call.  This
 | ||
| is to help do the RightThing when calls to these two functions are
 | ||
| nested, or if calls to external code in other extension modules that
 | ||
| are wrapped in the standard Py_(BEGIN|END)_ALLOW_THERADS may result in
 | ||
| wx event handlers being called (such as during the call to
 | ||
| os.startfile.)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Two (or Three!) Phase Create
 | ||
| ----------------------------
 | ||
| 
 | ||
| If you use the Precreate/Create method of instantiating a window, (for
 | ||
| example, to set an extended style flag, or for XRC handlers) then
 | ||
| there is now a new method named PostCreate to help with transplanting
 | ||
| the brain of the prewindow instance into the derived window instance.
 | ||
| For example::
 | ||
| 
 | ||
|     class MyDialog(wx.Dialog):
 | ||
|         def __init__(self, parent, ID, title, pos, size, style):
 | ||
|             pre = wx.PreDialog()
 | ||
|             pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
 | ||
|             pre.Create(parent, ID, title, pos, size, style)
 | ||
|             self.PostCreate(pre)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Sizers
 | ||
| ------
 | ||
| 
 | ||
| The hack allowing the old "option" keyword parameter has been removed.
 | ||
| If you use keyword args with wx.Sizer Add, Insert, or Prepend methods
 | ||
| then you will need to use the ``proportion`` name instead of
 | ||
| ``option``.  (The ``proportion`` keyword was also allowed in 2.4.2.4.)
 | ||
| 
 | ||
| When adding a spacer to a sizer you now need to use a wx.Size or a
 | ||
| 2-integer sequence instead of separate width and height parameters.
 | ||
| This was optionally allowed in 2.4, but now it is required.  This
 | ||
| allows for more consistency in how you add the various types of items
 | ||
| to a sizer.  The first parameter defines the item (instead of the
 | ||
| possibily first two, depending on if you are doing a spacer or not,)
 | ||
| and that item can either be a window, a sizer or a spacer (which can
 | ||
| be a sequence or a wx.Size.)  Removing the option for separate width
 | ||
| and height parameters greatly simplified the wrapper code.
 | ||
| 
 | ||
| The wx.GridBagSizer class (very similar to the RowColSizer in the
 | ||
| library) has been added to C++ and wrapped for wxPython.  It can also
 | ||
| be used from XRC.
 | ||
| 
 | ||
| You should not use AddWindow, AddSizer, AddSpacer (and similar for
 | ||
| Insert, Prepend, and etc.) methods any longer.  Just use Add and the
 | ||
| wrappers will figure out what to do.  **[Changed in 2.5.2.x]**
 | ||
| AddWindow, AddSizer, AddSpacer and etc. will now issue a
 | ||
| DeprecationWarning. **[Changed in 2.5.4.x]** These methods have now
 | ||
| been undeprecated at the request of Riaan Booysen, the Boa Constructor
 | ||
| team lead.  They are now just simple compatibility aliases for Add,
 | ||
| and etc.
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** The Sizers have had some fundamental internal
 | ||
| changes in the 2.5.2.x release intended to make them do more of the
 | ||
| "Right Thing" but also be as backwards compatible as possible.
 | ||
| First a bit about how things used to work:
 | ||
| 
 | ||
|     * The size that a window had when Add()ed to the sizer was assumed
 | ||
|       to be its minimal size, and that size would always be used by
 | ||
|       default when calculating layout size and positions, and the
 | ||
|       sizer itself would keep track of that minimal size.
 | ||
| 
 | ||
|     * If the window item was added with the ``wx.ADJUST_MINSIZE``
 | ||
|       flag then when layout was calculated the item's ``GetBestSize``
 | ||
|       would be used to reset the minimal size that the sizer used.
 | ||
| 
 | ||
| The main thrust of the new Sizer changes was to make behavior like
 | ||
| ``wx.ADJUST_MINSIZE`` be the default, and also to push the tracking of
 | ||
| the minimal size to the window itself (since it knows its own needs)
 | ||
| instead of having the sizer take care of it.  Consequently these
 | ||
| changes were made:
 | ||
| 
 | ||
|     * The ``wx.FIXED_MINSIZE`` flag was added to allow for the old
 | ||
|       behavior.  When this flag is used the size a window has when
 | ||
|       added to the sizer will be treated as its minimal size and it
 | ||
|       will not be readjusted on each layout.
 | ||
| 
 | ||
|     * The min size stored in ``wx.Window`` and settable with
 | ||
|       ``SetSizeHints`` or ``SetMinSize`` will by default be used by
 | ||
|       the sizer (if it was set) as the minimal size of the sizer item.
 | ||
|       If the min size was not set (or was only partially set) then the
 | ||
|       window's best size is fetched and it is used instead of (or
 | ||
|       blended with) the min size.  ``wx.Window.GetBestFittingSize``
 | ||
|       was added to facilitate getting the size to be used by the
 | ||
|       sizers.
 | ||
| 
 | ||
|     * The best size of a window is cached so it doesn't need to
 | ||
|       recaculated on every layout.  ``wx.Window.InvalidateBestSize``
 | ||
|       was added and should be called (usually just internally in
 | ||
|       control methods) whenever something is done that would make the
 | ||
|       best size change.
 | ||
| 
 | ||
|     * All wxControls were changed to set the minsize to what is passed
 | ||
|       to the constructor or Create method, and also to set the real
 | ||
|       size of the control to the blending of the min size and best
 | ||
|       size.  ``wx.Window.SetBestFittingSize`` was added to help with
 | ||
|       this, although most controls don't need to call it directly
 | ||
|       because it is called indirectly via the ``SetInitialSize``
 | ||
|       called in the base classes.
 | ||
| 
 | ||
| At this time, the only situation known not to work the same as before
 | ||
| is the following::
 | ||
| 
 | ||
| 	 win = SomeWidget(parent)
 | ||
| 	 win.SetSize(SomeNonDefaultSize)
 | ||
| 	 sizer.Add(win)
 | ||
| 
 | ||
| In this case the old code would have used the new size as the minimum,
 | ||
| but now the sizer will use the default size as the minimum rather than
 | ||
| the size set later.  It is an easy fix though, just move the
 | ||
| specification of the size to the constructor (assuming that SomeWidget
 | ||
| will set its minsize there like the rest of the controls do) or call
 | ||
| ``SetMinSize`` instead of ``SetSize``.
 | ||
| 
 | ||
| In order to fit well with this new scheme of things, all wxControls or
 | ||
| custom controls should do the following things.  (Depending on how
 | ||
| they are used you may also want to do the same thing for non-control
 | ||
| custom windows.)
 | ||
| 
 | ||
|     * Either override or inherit a meaningful ``DoGetBestSize`` method
 | ||
|       that calculates whatever size is "best" for the control.  Once
 | ||
|       that size is calculated then there should normally be a call to
 | ||
|       ``CacheBestSize`` to save it for later use, unless for some
 | ||
|       reason you want the best size to be recalculated on every
 | ||
|       layout.  
 | ||
| 
 | ||
|       Note: In order to successfully override ``DoGetBestSize`` in
 | ||
|       Python the class needs to be derived from ``wx.PyWindow``,
 | ||
|       ``wx.PyControl``, or etc.  If your class instead derives from
 | ||
|       one of the standard wx classes then just be sure that the min
 | ||
|       size gets explicitly set to what would have been the best size
 | ||
|       and things should work properly in almost all situations.
 | ||
| 
 | ||
|     * Any method that changes the attributes of the control such that
 | ||
|       the best size will change should call ``InvalidateBestSize`` so
 | ||
|       it will be recalculated the next time it is needed.
 | ||
| 
 | ||
|     * The control's constructor and/or Create method should ensure
 | ||
|       that the minsize is set to the size passed in, and that the
 | ||
|       control is sized to a blending of the min size and best size.
 | ||
|       This can be done by calling ``SetBestFittingSize``.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| PlatformInfo
 | ||
| ------------
 | ||
| 
 | ||
| Added wx.PlatformInfo which is a tuple containing strings that
 | ||
| describe the platform and build options of wxPython.  This lets you
 | ||
| know more about the build than just the __WXPORT__ value that
 | ||
| wx.Platform contains, such as if it is a GTK2 build.  For example,
 | ||
| instead of::
 | ||
| 
 | ||
|      if wx.Platform == "__WXGTK__":
 | ||
|          ...
 | ||
| 
 | ||
| you should do this::
 | ||
| 
 | ||
|     if "__WXGTK__" in wx.PlatformInfo:
 | ||
|          ...
 | ||
| 
 | ||
| and you can specifically check for a wxGTK2 build by looking for
 | ||
| "gtk2" in wx.PlatformInfo.  Unicode builds are also detectable this
 | ||
| way.  If there are any other platform/toolkit/build flags that make
 | ||
| sense to add to this tuple please let me know.
 | ||
| 
 | ||
| BTW, wx.Platform will probably be deprecated in the future.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ActiveX
 | ||
| -------
 | ||
| 
 | ||
| Lindsay Mathieson's newest wxActiveX_ class has been wrapped into a new
 | ||
| extension module called wx.activex.  It is very generic and dynamic
 | ||
| and should allow hosting of arbitray ActiveX controls within your
 | ||
| wxPython apps.  So far I've tested it with IE, PDF, and Flash
 | ||
| controls, (and there are new samples in the demo and also library
 | ||
| modules supporting these.)
 | ||
| 
 | ||
| .. _wxActiveX: http://members.optusnet.com.au/~blackpaw1/wxactivex.html
 | ||
| 
 | ||
| The new wx.activex module contains a bunch of code, but the most
 | ||
| important things to look at are ActiveXWindow and ActiveXEvent.
 | ||
| ActiveXWindow derives from wxWindow and the constructor accepts a
 | ||
| CLSID for the ActiveX Control that should be created.  (There is also
 | ||
| a CLSID class that can convert from a progID or a CLSID String.)  The
 | ||
| ActiveXWindow class simply adds methods that allow you to query some
 | ||
| of the TypeInfo exposed by the ActiveX object, and also to get/set
 | ||
| properties or call methods by name.  The Python implementation
 | ||
| automatically handles converting parameters and return values to/from
 | ||
| the types expected by the ActiveX code as specified by the TypeInfo,
 | ||
| (just bool, integers, floating point, strings and None/Empty so far,
 | ||
| but more can be handled later.)
 | ||
| 
 | ||
| That's pretty much all there is to the class, as I mentioned before it
 | ||
| is very generic and dynamic.  Very little is hard-coded and everything
 | ||
| that is done with the actual ActiveX control is done at runtime and
 | ||
| referenced by property or method name.  Since Python is such a dynamic
 | ||
| language this is a very good match.  I thought for a while about doing
 | ||
| some Python black-magic and making the specific methods/properties of
 | ||
| the actual ActiveX control "appear" at runtime, but then decided that
 | ||
| it would be better and more understandable to do it via subclassing.
 | ||
| So there is a utility class in wx.activex that given an existing
 | ||
| ActiveXWindow instance can generate a .py module containing a derived
 | ||
| class with real methods and properties that do the Right Thing to
 | ||
| reflect those calls to the real ActiveX control.  There is also a
 | ||
| script/tool module named genaxmodule that given a CLSID or progID and
 | ||
| a class name, will generate the module for you.  There are a few
 | ||
| examples of the output of this tool in the wx.lib package, see
 | ||
| iewin.py, pdfwin.py and flashwin.py.
 | ||
| 
 | ||
| Currently the genaxmodule tool will tweak some of the names it
 | ||
| generates, but this can be controled if you would like to do it
 | ||
| differently by deriving your own class from GernerateAXModule,
 | ||
| overriding some methods and then using this class from a tool like
 | ||
| genaxmodule.  [TODO: make specifying a new class on genaxmodule's
 | ||
| command-line possible.]  The current default behavior is that any
 | ||
| event names that start with "On" will have the "On" dropped, property
 | ||
| names are converted to all lower case, and if any name is a Python
 | ||
| keyword it will have an underscore appended to it.  GernerateAXModule
 | ||
| does it's best when generating the code in the new module, but it can
 | ||
| only be as good as the TypeInfo data available from the ActiveX
 | ||
| control so sometimes some tweaking will be needed.  For example, the
 | ||
| IE web browser control defines the Flags parameter of the Navigate2
 | ||
| method as required, but MSDN says it is optional.
 | ||
| 
 | ||
| It is intended that this new wx.activex module will replace both the
 | ||
| older version of Lindsay's code available in iewin.IEHtmlWindow, and
 | ||
| also the wx.lib.activexwraper module.  Probably the biggest
 | ||
| differences you'll ecounter in migrating activexwrapper-based code
 | ||
| (besides events working better without causing deadlocks) is that
 | ||
| events are no longer caught by overriding methods in your derived
 | ||
| class.  Instead ActiveXWindow uses the wx event system and you bind
 | ||
| handlers for the ActiveX events exactly the same way you do for any wx
 | ||
| event.  There is just one extra step needed and that is creating an
 | ||
| event ID from the ActiveX event name, and if you use the genaxmodule
 | ||
| tool then this extra step will be handled for you there.  For example,
 | ||
| for the StatusTextChange event in the IE web browser control, this
 | ||
| code is generated for you::
 | ||
| 
 | ||
|     wxEVT_StatusTextChange = wx.activex.RegisterActiveXEvent('StatusTextChange')
 | ||
|     EVT_StatusTextChange = wx.PyEventBinder(wxEVT_StatusTextChange, 1)
 | ||
| 
 | ||
| and you would use it in your code like this::
 | ||
| 
 | ||
|     self.Bind(iewin.EVT_StatusTextChange, self.UpdateStatusText, self.ie)
 | ||
| 
 | ||
| When the event happens and your event handler function is called the
 | ||
| event properties from the ActiveX control (if any) are converted to
 | ||
| attributes of the event object passed to the handler.  (Can you say
 | ||
| 'event' any more times in a single sentence? ;-) ) For example the
 | ||
| StatusTextChange event will also send the text that should be put into
 | ||
| the status line as an event parameter named "Text" and you can access
 | ||
| it your handlers as an attribute of the event object like this::
 | ||
| 
 | ||
|     def UpdateStatusText(self, evt):
 | ||
|         self.SetStatusText(evt.Text)
 | ||
| 
 | ||
| Usually these event object attributes should be considered read-only,
 | ||
| but some will be defined by the TypeInfo as output parameters.  In
 | ||
| those cases if you modify the event object's attribute then that value
 | ||
| will be returned to the ActiveX control.  For example, to prevent a
 | ||
| new window from being opened by the IE web browser control you can do
 | ||
| this in the handler for the iewin.EVT_NewWindow2 event::
 | ||
| 
 | ||
|     def OnNewWindow2(self, evt):
 | ||
|         evt.Cancel = True   
 | ||
| 
 | ||
| So how do you know what methods, events and properties that an ActiveX
 | ||
| control supports?  There is a funciton in wx.activex named GetAXInfo
 | ||
| that returns a printable summary of the TypeInfo from the ActiveX
 | ||
| instance passed in.  You can use this as an example of how to browse
 | ||
| the TypeInfo provided, and there is also a copy of this function's
 | ||
| output appended as a comment to the modules produced by the
 | ||
| genaxmodule tool.  Beyond that you'll need to consult the docs
 | ||
| provided by the makers of the ActiveX control that you are using.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| PNG Images
 | ||
| ----------
 | ||
| 
 | ||
| Prior to 2.5 the PNG image handler would convert all alpha channel
 | ||
| information to a mask when the image was loaded.  Pixels that were
 | ||
| more than halfway transparent would be made fully transparent by the
 | ||
| mask and the rest would be made fully opaque.
 | ||
| 
 | ||
| In 2.5 the image handler has been updated to preserve the alpha
 | ||
| channel and will now only create a mask when all the pixels in the
 | ||
| image are either fully transparent or fully opaque.  In addition, the
 | ||
| wx.DC.DrawBitmap and wx.DC.Blit methods are able to correctly blend
 | ||
| the pixels in the image with partially transparent alpha values.
 | ||
| 
 | ||
| If you are using a PNG with an alpha channel but you need to have a
 | ||
| wx.Mask like you automatically got in 2.4 then you can do one of the
 | ||
| following:
 | ||
| 
 | ||
|     * Edit the image and make all the partially transparent pixels be
 | ||
|       fully transparent.
 | ||
| 
 | ||
|     * Use a different image type.
 | ||
| 
 | ||
|     * Set a mask based on colour after you load the image.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| OGL is dead! LONG LIVE OGL!
 | ||
| ---------------------------
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** 
 | ||
| 
 | ||
| The wx.ogl module was deprecated in version 2.5.2 in favor of the new
 | ||
| Python port of the OGL library located at wx.lib.ogl contributed by
 | ||
| Pierre Hj<48>lm.  Starting in version 2.5.5 the old ogl is no longer
 | ||
| being built in the distributed binaries, however the source code is
 | ||
| still in the source tree so people can built it themselves if desired.
 | ||
| 
 | ||
| The reason this changes was done was to greatly extend the life of OGL
 | ||
| within wxPython by making it more easily maintainable and less prone
 | ||
| to getting rusty as there seems to be less and less interest in
 | ||
| maintaining the C++ version.
 | ||
| 
 | ||
| There are only a few known compatibility issues at this time.  First
 | ||
| is the location of OGL.  The old version was located in the
 | ||
| wx.ogl module, and the new version is in the wx.lib.ogl package.  So
 | ||
| this just means that to start using the new version you need to adjust
 | ||
| your imports.  So if your code currently has something like this::
 | ||
| 
 | ||
|      import wx
 | ||
|      import wx.ogl as ogl
 | ||
| 
 | ||
| Then just change it to this::
 | ||
| 
 | ||
|      import wx
 | ||
|      import wx.lib.ogl as ogl
 | ||
| 
 | ||
| The other compatibility issue deals with removing a wart in the
 | ||
| original API that was necessary in order to allow overloaded methods
 | ||
| in derived classes to call the same method in the base class when
 | ||
| using the old SWIG.  Instead dedaling with the wart you can now just
 | ||
| call the base class method like you woudl for any other Python class.
 | ||
| For example, if you had to do something like this previously::
 | ||
| 
 | ||
|     class MyDividedShape(ogl.DividedShape):
 | ||
|         ...
 | ||
|         def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | ||
|             self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
 | ||
|             ...
 | ||
| 
 | ||
| You will need to change it to be like this::
 | ||
| 
 | ||
|     class MyDividedShape(ogl.DividedShape):
 | ||
|         ...
 | ||
|         def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | ||
|             ogl.DividedShape.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
 | ||
|             ...    
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Obsolete Modules
 | ||
| ----------------
 | ||
| 
 | ||
| Instead of over a dozen separate extension modules linked together
 | ||
| into a single extension module, the "core" module is now just a few
 | ||
| extensions that are linked independently, and then merged together
 | ||
| later into the main namespace via Python code.
 | ||
| 
 | ||
| Because of the above and also because of the way the new SWIG works,
 | ||
| the "internal" module names have changed, but you shouldn't have been
 | ||
| using them anyway so it shouldn't bother you. ;-) In case you were
 | ||
| erroneously using them in 2.4, here are the internal extension modules
 | ||
| that no longer exist:
 | ||
| 
 | ||
|     * clip_dnd
 | ||
|     * cmndlgs
 | ||
|     * controls
 | ||
|     * controls2
 | ||
|     * events
 | ||
|     * filesys
 | ||
|     * fonts
 | ||
|     * frames
 | ||
|     * gdi
 | ||
|     * image
 | ||
|     * mdi
 | ||
|     * misc
 | ||
|     * misc2
 | ||
|     * printfw
 | ||
|     * sizers
 | ||
|     * stattool
 | ||
|     * streams
 | ||
|     * utils
 | ||
|     * windows
 | ||
|     * windows2
 | ||
|     * windows3
 | ||
| 
 | ||
| They have been replaced by the following, but please remember that
 | ||
| these are just "implementation details" and you should really be using
 | ||
| the objects in these modules only via the wx or wxPython.wx packages:
 | ||
| 
 | ||
|     * _core
 | ||
|     * _gdi
 | ||
|     * _windows
 | ||
|     * _controls
 | ||
|     * _misc
 | ||
| 
 | ||
| 
 | ||
| The help module no longer exists and the classes therein are now part
 | ||
| of the core module imported with wxPython.wx or the wx package.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| wx.TaskBarIcon
 | ||
| --------------
 | ||
| 
 | ||
| **[Changed in 2.5.3.x]** 
 | ||
| 
 | ||
| wx.TaskbarIcon now works on all three platforms, although for wxGTK it
 | ||
| depends on support from the Window Manager.  On OS X the icon replaces
 | ||
| the application's icon on the dock and when you right click on it the
 | ||
| app's default popup menu is merged with the wx.TaskBarIcon's menu.
 | ||
| Because of how it is implemented on the Mac using the Dock most of the
 | ||
| TaskBarIcon events will _not_ be emitted on that platform, but since
 | ||
| 98% of the time you simply want to display an icon and have a popup
 | ||
| menu it shouldn't be much of a problem.  You can still use the other
 | ||
| events on the other platforms, you'll just want to be sure that you
 | ||
| can do everything you want via the menu too.
 | ||
| 
 | ||
| Since popping up a menu is the most common thing to do with a
 | ||
| TaskBarIcon the class has some new built in functionality to
 | ||
| facilitate that.  To use the TaskBarIcon in this new way, simply
 | ||
| derive a new class from TaskBarIcon and implement a CreatePopupMenu
 | ||
| method that creates and returns the menu.  That's all there is to it,
 | ||
| besides binding event handlers for the menu items of course.  Take a
 | ||
| look at the DemoTaskBarIcon class in the demo/Main.py module for an
 | ||
| example.
 | ||
| 
 | ||
| **NOTE**:  Unfortunately due to being able to support virtualizing
 | ||
| CreatePopupMenu the C++ TaskBarIcon instance now holds a reference to
 | ||
| the Python instance, and so you will need to explicitly Destroy() your
 | ||
| TaskBarIcon instance when you are done with it.  (Like you do with
 | ||
| wx.Dialogs.)  If you don't destroy it then wxWidgets will assume that
 | ||
| you want the app to keep running with just the icon in the task bar
 | ||
| and the MainLoop will not exit.
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Version Number Change
 | ||
| ---------------------
 | ||
| 
 | ||
| **[Changed in 2.5.3.x]** 
 | ||
| 
 | ||
| Starting with 2.5.3.0 the Unicode versions of wxPython will no longer
 | ||
| have a 'u' appended to the fourth component of the version number.
 | ||
| Please check for the presence of "unicode" in the `wx.PlatformInfo`
 | ||
| tuple instead.  (This tuple of strings has been available since the
 | ||
| first 2.5 version.) For example::
 | ||
| 
 | ||
|      if "unicode" in wx.PlatformInfo:
 | ||
|          # do whatever
 | ||
| 	 ...
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Multi-Version Installs
 | ||
| ----------------------
 | ||
| 
 | ||
| **[Changed in 2.5.3.x]** 
 | ||
| 
 | ||
| Starting with 2.5.3.0 the wx and wxPython package directories will be
 | ||
| installed in a subdirectory of the site-packages directory, instead of
 | ||
| directly in site-packages.  This is done to help facilitate having
 | ||
| multiple versions of wxPython installed side-by-side.  Why would you
 | ||
| want to do this?  One possible scenario is you have an app that
 | ||
| requires wxPython 2.4 but you want to use the newest 2.5 to do your
 | ||
| own development with.  Or perhaps you want to be able to test your app
 | ||
| with several different versions of wxPython to ensure compatibility.
 | ||
| Before everyone panics, rest asured that if you only install one
 | ||
| version of wxPython then you should notice no difference in how things
 | ||
| work.
 | ||
| 
 | ||
| In addition to installing wxPython into a "versioned" subdirectory of
 | ||
| site-packages, a file named `wx.pth` is optionally installed that will
 | ||
| contain the name of the versioned subdirectory.  This will cause that
 | ||
| subdirectory to be automatically added to the sys.path and so doing an
 | ||
| "import wx" will find the package in the subdirectory like it would
 | ||
| have if it was still located directly in site-packages.  I say
 | ||
| "optionally" above because that is how you can control which install
 | ||
| of wxPython is the default one.  Which ever version installs the
 | ||
| wx.pth file will be the one that is imported with a plain "import wx"
 | ||
| statement.  Of course you can always manipulate that by editing the
 | ||
| wx.pth file, or by setting PYTHONPATH in the environment, or by the
 | ||
| method described in the next paragraph.
 | ||
| 
 | ||
| Finally, a new module named wxversion.py is installed to the
 | ||
| site-packages directory.  It can be used to manipulate the sys.path at
 | ||
| runtime so your applications can select which version of wxPython they
 | ||
| would like to to have imported.  You use it like this::
 | ||
| 
 | ||
|       import wxversion
 | ||
|       wxversion.select("2.4")
 | ||
|       import wx
 | ||
| 
 | ||
| Then even though a 2.5 version of wxPython may be the default the
 | ||
| application that does the above the first time that wx is imported
 | ||
| will actually get a 2.4 version.  **NOTE:** There isn't actually a 2.4
 | ||
| version of wxPython that supports this, but there will be.
 | ||
| 
 | ||
| Please see this wiki page for more details, HowTo's and FAQ's:
 | ||
| http://wiki.wxpython.org/index.cgi/MultiVersionInstalls
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Miscellaneous Stuff
 | ||
| -------------------
 | ||
| 
 | ||
| wxPyDefaultPosition and wxPyDefaultSize are gone.  Use the
 | ||
| wxDefaultPosition and wxDefaultSize objects instead.
 | ||
| 
 | ||
| Similarly, the wxSystemSettings backwards compatibiility aliases for
 | ||
| GetSystemColour, GetSystemFont and GetSystemMetric have also gone into
 | ||
| the bit-bucket.  Use GetColour, GetFont and GetMetric instead.
 | ||
| 
 | ||
| Use the Python True/False constants instead of the true, TRUE, false,
 | ||
| FALSE that used to be provided with wxPython.
 | ||
| 
 | ||
| Use None instead of the ancient and should have been removed a long
 | ||
| time ago wx.NULL alias.
 | ||
| 
 | ||
| wx.TreeCtrl.GetFirstChild no longer needs to be passed the cookie
 | ||
| variable as the 2nd parameter.  It still returns it though, for use
 | ||
| with GetNextChild.
 | ||
| 
 | ||
| The wx.NO_FULL_REPAINT_ON_RESIZE style is now the default style for
 | ||
| all windows.  The name still exists for compatibility, but it is set
 | ||
| to zero.  If you want to disable the setting (so it matches the old
 | ||
| default) then you need to use the new wx.FULL_REPAINT_ON_RESIZE style
 | ||
| flag otherwise only the freshly exposed areas of the window will be
 | ||
| refreshed.
 | ||
| 
 | ||
| wxPyTypeCast has been removed.  Since we've had the OOR (Original
 | ||
| Object Return) for a couple years now there should be no need to use
 | ||
| wxPyTypeCast at all.
 | ||
| 
 | ||
| If you use the old wxPython package and wxPython.wx namespace then
 | ||
| there are compatibility aliases for much of the above items.
 | ||
| 
 | ||
| The wxWave class has been renamed to wxSound, and now has a slightly
 | ||
| different API.
 | ||
| 
 | ||
| Before Python 2.3 it was possible to pass a floating point object as a
 | ||
| parameter to a function that expected an integer, and the
 | ||
| PyArg_ParseTuple family of functions would automatically convert to
 | ||
| integer by truncating the fractional portion of the number.  With
 | ||
| Python 2.3 that behavior was deprecated and a deprecation warning is
 | ||
| raised when you pass a floating point value, (for example, calling
 | ||
| wx.DC.DrawLine with floats for the position and size,) and lots of
 | ||
| developers using wxPython had to scramble to change their code to call
 | ||
| int() before calling wxPython methods.  Recent changes in SWIG have
 | ||
| moved the conversion out of PyArg_ParseTuple to custom code that SWIG
 | ||
| generates.  Since the default conversion fragment was a little too
 | ||
| strict and didn't generate a very meaningful exception when it failed,
 | ||
| I decided to use a custom fragment instead, and it turned out that
 | ||
| it's very easy to allow floats to be converted again just like they
 | ||
| used to be.   So, in a nutshell, any numeric type that can be
 | ||
| converted to an integer is now legal to be passed to SWIG wrapped
 | ||
| functions in wxPython for parameters that are expecting an integer.
 | ||
| If the object is not already an integer then it will be asked to
 | ||
| convert itself to one.  A similar conversion fragment is in place for
 | ||
| parameters that expect floating point values.
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]**  The MaskedEditCtrl modules have been moved
 | ||
| to their own sub-package, wx.lib.masked.  See the docstrings and demo
 | ||
| for changes in capabilities, usage, etc.
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** wx.MaskColour constructor has been deprecated
 | ||
| and will raise a DeprecationWarning if used.  The main wx.Mask
 | ||
| constructor has been modified to be compatible with wx.MaskColour so
 | ||
| you should use it instead.
 | ||
| 
 | ||
| **[Changed in 2.5.2.x]** In wx.TextCtrls that have the
 | ||
| wx.TE_PROCESS_TAB style the TAB key will be treated like an ordinary
 | ||
| character and will not cause any tab traversal navigation at all.  If
 | ||
| you use this style but would still like to have the normal tab
 | ||
| traversal take place then you should send your own
 | ||
| wx.NavigationKeyEvent from the wx.EVT_KEY_DOWN handler.  There is a
 | ||
| new Navigate method in the wx.Window class to help send the event and
 | ||
| it is used something like this::
 | ||
| 
 | ||
| 	flags = wx.NavigationKeyEvent.IsForward
 | ||
| 	if event.ShiftDown():
 | ||
| 	    flags = wx.NavigationKeyEvent.IsBackward
 | ||
| 	if event.ControlDown():
 | ||
| 	    flags |= wx.NavigationKeyEvent.WinChange
 | ||
| 	self.Navigate(flags)
 | ||
| 
 | ||
| 
 |