git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26581 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			651 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			651 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
============================
 | 
						|
wxPython 2.5 Migration Guide
 | 
						|
============================
 | 
						|
 | 
						|
This document will help explain some of the major changes in wxPython
 | 
						|
2.5 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 will be changing to wxwidgets.org,
 | 
						|
so mail list, CVS, and etc. addresses will be changing.  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.)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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"
 | 
						|
 | 
						|
    Public data members of the C++ classes are wrapped as Python
 | 
						|
    properties using property() instead of using __getattr__/__setattr__
 | 
						|
    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 available as top level functions
 | 
						|
    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 wxFoo even if they are created internally using wxFooPtr,
 | 
						|
    because wxFooPtr.__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, wxFooPtr) you will
 | 
						|
    need to change it to isinstance(obj, wxFoo).
 | 
						|
 | 
						|
    
 | 
						|
 | 
						|
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 wxPyEventBinder 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.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
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
 | 
						|
-----------------
 | 
						|
 | 
						|
Many of the Draw methods of wx.DC have alternate forms in C++ that take
 | 
						|
wxPoint or wxSize parameters (let's call these *Type A*) instead of
 | 
						|
the individual x, y, width, height, etc. parameters (and we'll call
 | 
						|
these *Type B*).  In the rest of the library I normally made the *Type
 | 
						|
A* forms of the methods be the default method with the "normal" name,
 | 
						|
and had renamed the *Type B* forms of the methods to some similar
 | 
						|
name.  For example in wx.Window we have these Python methods::
 | 
						|
 | 
						|
    SetSize(size)               # Type A
 | 
						|
    SetSizeWH(width, height)    # Type B
 | 
						|
 | 
						|
 | 
						|
For various reasons the new *Type A* methods in wx.DC were never added
 | 
						|
and the existing *Type B* methods were never renamed.  Now that lots
 | 
						|
of other things are also changing in wxPython it has been decided that
 | 
						|
it is a good time to also do the method renaming in wx.DC too in order
 | 
						|
to be consistent with the rest of the library.  The methods in wx.DC
 | 
						|
that are affected are listed here::
 | 
						|
 | 
						|
    FloodFillXY(x, y, colour, style = wx.FLOOD_SURFACE)
 | 
						|
    FloodFill(point, colour,  style = wx.FLOOD_SURFACE)
 | 
						|
 | 
						|
    GetPixelXY(x, y)
 | 
						|
    GetPixel(point)
 | 
						|
 | 
						|
    DrawLineXY(x1, y1, x2, y2)
 | 
						|
    DrawLine(point1, point2)
 | 
						|
 | 
						|
    CrossHairXY(x, y)
 | 
						|
    CrossHair(point)
 | 
						|
 | 
						|
    DrawArcXY(x1, y1, x2, y2, xc, yc)
 | 
						|
    DrawArc(point1, point2, center)
 | 
						|
 | 
						|
    DrawCheckMarkXY(x, y, width, height)
 | 
						|
    DrawCheckMark(rect)
 | 
						|
 | 
						|
    DrawEllipticArcXY(x, y, w, h, start_angle, end_angle)
 | 
						|
    DrawEllipticArc(point, size, start_angle, end_angle)
 | 
						|
 | 
						|
    DrawPointXY(x, y)
 | 
						|
    DrawPoint(point)
 | 
						|
 | 
						|
    DrawRectangleXY(x, y, width, height)
 | 
						|
    DrawRectangle(point, size)
 | 
						|
    DrawRectangleRect(rect)
 | 
						|
 | 
						|
    DrawRoundedRectangleXY(x, y, width, height, radius)
 | 
						|
    DrawRoundedRectangle(point, size, radius)
 | 
						|
    DrawRoundedRectangleRect(rect, radius)
 | 
						|
 | 
						|
    DrawCircleXY(x, y, radius)
 | 
						|
    DrawCircle(point, radius)
 | 
						|
 | 
						|
    DrawEllipseXY(x, y, width, height)
 | 
						|
    DrawEllipse(point, size)
 | 
						|
    DrawEllipseRect(rect)
 | 
						|
 | 
						|
    DrawIconXY(icon, x, y)
 | 
						|
    DrawIcon(icon, point)
 | 
						|
 | 
						|
    DrawBitmapXY(bmp, x, y, useMask = FALSE)
 | 
						|
    DrawBitmap(bmp, point, useMask = FALSE)
 | 
						|
 | 
						|
    DrawTextXY(text, x, y)
 | 
						|
    DrawText(text, point)
 | 
						|
 | 
						|
    DrawRotatedTextXY(text, x, y, angle)
 | 
						|
    DrawRotatedText(text, point, angle)
 | 
						|
 | 
						|
    
 | 
						|
    BlitXY(xdest, ydest, width, height, sourceDC, xsrc, ysrc,
 | 
						|
           rop = wxCOPY, useMask = FALSE, xsrcMask = -1, ysrcMask = -1)
 | 
						|
    Blit(destPt, size, sourceDC, srcPt,
 | 
						|
         rop = wxCOPY, useMask = FALSE, srcPtMask = wx.DefaultPosition)
 | 
						|
 | 
						|
    SetClippingRegionXY(x, y, width, height)
 | 
						|
    SetClippingRegion(point, size)
 | 
						|
    SetClippingRect(rect)
 | 
						|
    SetClippingRegionAsRegion(region);
 | 
						|
 | 
						|
	
 | 
						|
If you have code that draws on a DC and you are using the new wx
 | 
						|
namespace then you **will** get errors because of these changes, but
 | 
						|
it should be easy to fix the code.  You can either change the name of
 | 
						|
the *Type B* method called to the names shown above, or just add
 | 
						|
parentheses around the parameters as needed to turn them into tuples
 | 
						|
and let the SWIG typemaps turn them into the wx.Point or wx.Size
 | 
						|
object that is expected.  Then you will be calling the new *Type A*
 | 
						|
method.  For example, if you had this code before::
 | 
						|
 | 
						|
    dc.DrawRectangle(x, y, width, height)
 | 
						|
 | 
						|
You could either continue to use the *Type B* method by changing the
 | 
						|
name to DrawRectangleXY, or just change it to the new *Type A* by
 | 
						|
adding some parentheses like this::
 | 
						|
 | 
						|
    dc.DrawRectangle((x, y), (width, height))
 | 
						|
 | 
						|
Or if you were already using a point and size like this::
 | 
						|
 | 
						|
    dc.DrawRectangle(p.x, p.y, s.width, s.height)
 | 
						|
 | 
						|
Then you can just simplify it like this::
 | 
						|
 | 
						|
    dc.DrawRectangle(p, s)
 | 
						|
 | 
						|
Now before you start yelling and screaming at me for breaking all your
 | 
						|
code, take note that up above I said, "...using the new wx namespace..."
 | 
						|
That's because if you are still importing from wxPython.wx then there
 | 
						|
are some classes defined there with Draw and etc. methods that have
 | 
						|
2.4 compatible signatures.  However if/when the old wxPython.wx
 | 
						|
namespace is removed then these classes will be removed too so you
 | 
						|
should plan on migrating to the new namespace and new DC Draw methods
 | 
						|
before that time.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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 ogl, stc, xrc, 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 w.xSizer Add, Insert, or Prepend methods
 | 
						|
then you will need to use the ``proportion`` name instead of ``option``.
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Other Stuff
 | 
						|
-----------
 | 
						|
 | 
						|
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. ;-)
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
wx.TaskbarIcon works on wxGTK-based platforms now, however you have to
 | 
						|
manage it a little bit more than you did before.  Basically, the app
 | 
						|
will treat it like a top-level frame in that if the wx.TaskBarIcon
 | 
						|
still exists when all the frames are closed then the app will still
 | 
						|
not exit.  You need to ensure that the wx.TaskBarIcon is destroyed
 | 
						|
when your last Frame is closed.  For wxPython apps it is usually
 | 
						|
enough if your main frame object holds the only reference to the
 | 
						|
wx.TaskBarIcon, then when the frame is closed Python reference
 | 
						|
counting takes care of the rest.
 | 
						|
 | 
						|
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.DrawLineXY 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.
 |