Following is a list of wxPython problems discovered while porting a medium-sized application to the Mac (CrossMgr, www.sites.google.com/site/crossmgrsoftware).
The solutions/workarounds are also documented below.
None of the fixes were all that difficult, but the solutions took weeks to find, so I am posting this for the greater good.
Thanks to all those on the forum who helped me along the way.
If anyone has some better suggestions, let me know.
System Details:
OSX: Mavericks, 64-bit Intel
Python: 2.7.5
wxPython: 2.9.5.0
LogPrintStackStderr.py (1.38 KB)
···
****Problem:
On Windows and Linux, wx errors are shown in stderr with a stack trace.
By default, errors on the Mac are shown in a dialog, but no stack trace, making it impossible to find out where the error is occurring.
Solution:
Write a custom error logger. See attachment “LogPrintStackStderr.py” for a logger that writes to stderr (you can modify on your own to write to the screen, if that’s what you want).
You then need to tell wx to use your new handler as follows:
import wx
from LogPrintStackStderr import LogPrintStackStderr
…
if ‘WXMAC’ in wx.Platform: # More reliable than getting the right number of underscores are in WXMAC.
wx.Log.SetActiveTarget( LogPrintStackStderr() )
…
****Problem:
wx.Button does not draw properly with a larger font. The button keeps the standard height, but the text spills outside of the button’s borders on top and bottom.
This is especially problematic on touch-screen-friendly displays designed with larger buttons.
Solution:
Use wx.lib.buttons.ThemedGenButton instead. They do not match the Mac look-and-feel, but look better than plain GenButton. They will draw in the proper height with a larger font.
Example:
import wx.lib.buttons
…
btn = wx.lib.buttons.ThemedGenButton( parent, label=‘Big Font Button’ )
btn.SetFont( wx.FontFromPixelSize(wx.Size(0,64), wx.DEFAULT, wx.NORMAL, wx.NORMAL) )
…
****Problem:
A wx.TextCtrl does not adjust its height to accommodate a larger font. The wx.TextCtrl uses its standard height, even if the contents are illegible.
Solution:
Explicitly set the height to fontHeight*1.2 when you create the wx.TextCtrl.
import wx
…
fontSize = 64
font = wx.FontFromPixelSize(wx.Size(0,fontSize), wx.DEFAULT, wx.NORMAL, wx.NORMAL)
tc = wx.TextCtrl( parent, value=‘’, size=(-1, fontSize*1.2) )
tc.SetFont( font )
…
****Problem:
A wx.TextCtrl defaults to one line in height even when style=wx.TE_MULTILINE. On Windows and Linux, wx.TE_MULTILINE shows at least two lines.
Solution:
Set the height to be larger than 1 line. Example:
tc = wx.TextCtrl( parent, value=‘’, size=(-1,96), style=wx.TE_MULTILINE )
****Problem:
wx.DC.GetMultiLineTextExtent function returns garbage, causing havoc in custom drawing routines that use it.
Solution:
Define your own, then monkey-patch over the non-working standard function:
if ‘WXMAC’ in wx.Platform:
# wx.DC.GetMultiLineTextExtent does not work on the Mac.
# Replace it with our own function.
def GetMultiLineTextExtent( dc, text, font = None ):
textWidth, textHeight, lineHeight = 0, 0, None
for line in text.split('\n'):
lineWidth, lineHeight = dc.GetFullTextExtent( line, font )[:2]
textWidth = max( textWidth, lineWidth )
textHeight += lineHeight
if lineHeight is None:
lineHeight = dc.GetFullTextExtent( '000Yy', font )[1]
return textWidth, textHeight, lineHeight
wx.DC.GetMultiLineTextExtent = GetMultiLineTextExtent
****Problem:
wx.MessageDialog shows a rocket ship instead of the appropriate Warning, Error or Information icon.
Solution:
Use the wx.lib.agw.genericmessagedialog.GenericMessageDialog instead. It does not match the Mac dialog look and feel, but it does display informative icons.
To replace wx.MessageDialog everywhere without changing your code, apply the following monkey-patch:
import wx
import wx.lib.agw.genericmessagedialog
if ‘WXMAC’ in wx.Platform:
wx.MessageDialog = wx.lib.agw.genericmessagedialog.GenericMessageDialog
****Problem:
Advanced Splash Screen does not work.
Solution:
Use the standard wx.SplashScreen instead - it works fine. Be satisfied with a rectangular splash screen, without the fancy features of the advanced splash.
Example:
import wx
…
wx.SplashScreen( bitmap, wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT, 2500, None )
…