Project Phoenix Porting Issues
In addition to the general information in the Phoenix Migration Guide (html or source text) this page can be used to document specific issues that developers run into when porting code from Classic wxPython to Phoenix, and what changes should be made to properly deal with or to work around those issues.
Anybody can make additions to this page as new issues and fixes are discovered. Just be sure that the fix you propose does in fact work and doesn't cause other problems. Try to write enough that others can easily understand both the problem and the solution. Once there are several items on a particular subject or class then create a new section for them so they are grouped together.
ComboCtrl and related items are now in the code namespace, so you can access them as wx.ComboCtrl and etc. instead of wx.combo.ComboCtrl.
Phoenix does not yet support inheriting from more than one wrapped C++ class, so classes derived from wx.ComboPopup and some widget class will need to be rewritten such that they derive from just wx.ComboPopup which then creates an instance of the widget and has methods that delegate to the widget as needed. In other words, instead of using a OOP "is-a" relationship, the popup should be implemented with a "has-a" relationship.
In 2-phase create situations you no longer need to call the 'Pre' version of the base class and do not need to call PostCreate. For example, this:
pre = wx.PreListCtrl() ... self.PostCreate(pre)should now be written as simply this:
The new technology used for Phoenix supports function and method overloading and therefore eliminates the need to have renamed versions of the same methods in order to wrap the overloaded C++ methods. For example instead of SetSize, SetSizeWH, and SetDimensions we can have just SetSize. Most of the time this is wonderful and can really simplify the code. However here is a case where it didn't work out so well:
// C++ fragment from the wxRect class wxRect(); wxRect(int xx, int yy, int ww, int hh); wxRect(const wxPoint& pos, const wxSize& size); // this one wxRect(const wxPoint& topLeft, const wxPoint& bottomRight); // and this one wxRect(const wxSize& size);
The constructors highlighted above have a hidden problem. One takes a wx.Point and a wx.Size and the other takes two wx.Point objects. Normally that would not be a problem, however since both the point and the size objects can be automatically converted from 2 element sequences of numbers then the code that figures out which version of the C++ function to call can not figure out which one you intended if you use sequences. The problem is further compounded by the fact that both wx.Point and wx.Size implement the sequence protocol methods so even if you have an actual wx.Point object it can be confused with a wx.Size object and the wrong constructor can be called. (The one called by default will be the first listed in the function signatures in the docstring.) The solution is simple however. You can use keyword args to explicitly choose which of those two constructors should be called. For example:
rect = wx.Rect(topLeft=pointA, bottomRight=pointB)