except NameError:
__builtins__.True = 1==1
__builtins__.False = 1==0
+ def bool(value): return not not value
+ __builtins__.bool = bool
#----------------------------------------------------------------------------
# Load version numbers from __version__... Ensure that major and minor
-# versions are the same for both wxPython and wxWindows.
+# versions are the same for both wxPython and wxWidgets.
from __version__ import *
__version__ = VERSION_STRING
-assert MAJOR_VERSION == _core.MAJOR_VERSION, "wxPython/wxWindows version mismatch"
-assert MINOR_VERSION == _core.MINOR_VERSION, "wxPython/wxWindows version mismatch"
-if RELEASE_VERSION != _core.RELEASE_VERSION:
+assert MAJOR_VERSION == _core_.MAJOR_VERSION, "wxPython/wxWidgets version mismatch"
+assert MINOR_VERSION == _core_.MINOR_VERSION, "wxPython/wxWidgets version mismatch"
+if RELEASE_VERSION != _core_.RELEASE_VERSION:
import warnings
- warnings.warn("wxPython/wxWindows release number mismatch")
+ warnings.warn("wxPython/wxWidgets release number mismatch")
+
+#----------------------------------------------------------------------------
+
+# Set wxPython's default string<-->unicode conversion encoding from
+# the locale, but only if Python's default hasn't been changed. (We
+# assume that if the user has customized it already then that is the
+# encoding we need to use as well.)
+#
+# The encoding selected here is used when string or unicode objects
+# need to be converted in order to pass them to wxWidgets. Please be
+# aware that the default encoding within the same locale may be
+# slightly different on different platforms. For example, please see
+# http://www.alanwood.net/demos/charsetdiffs.html for differences
+# between the common latin/roman encodings.
+
+default = _sys.getdefaultencoding()
+if default == 'ascii':
+ import locale
+ import codecs
+ try:
+ default = locale.getdefaultlocale()[1]
+ codecs.lookup(default)
+ except (ValueError, LookupError, TypeError):
+ default = _sys.getdefaultencoding()
+ del locale
+ del codecs
+if default:
+ wx.SetDefaultPyEncoding(default)
+del default
#----------------------------------------------------------------------------
class PyDeadObjectError(AttributeError):
pass
-
class _wxPyDeadObject(object):
"""
Instances of wx objects that are OOR capable will have their __class__
reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
- def __repr__( self ):
+ def __repr__(self):
if not hasattr(self, "_name"):
self._name = "[unknown]"
return self.reprStr % self._name
- def __getattr__( self, *args ):
+ def __getattr__(self, *args):
if not hasattr(self, "_name"):
self._name = "[unknown]"
- raise PyDeadObjectError( self.attrStr % self._name )
+ raise PyDeadObjectError(self.attrStr % self._name)
+
+ def __nonzero__(self):
+ return 0
+
+
+
+class PyUnbornObjectError(AttributeError):
+ pass
+
+class _wxPyUnbornObject(object):
+ """
+ Some stock objects are created when the wx._core module is
+ imported, but their C++ instance is not created until the wx.App
+ object is created and initialized. These object instances will
+ temporarily have their __class__ changed to this class so an
+ exception will be raised if they are used before the C++ instance
+ is ready.
+ """
+
+ reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)"
+ attrStr = "The C++ part of this object has not been initialized, attribute access not allowed."
+
+ def __repr__(self):
+ #if not hasattr(self, "_name"):
+ # self._name = "[unknown]"
+ return self.reprStr #% self._name
+
+ def __getattr__(self, *args):
+ #if not hasattr(self, "_name"):
+ # self._name = "[unknown]"
+ raise PyUnbornObjectError(self.attrStr) # % self._name )
def __nonzero__(self):
return 0
#----------------------------------------------------------------------------
-_wxPyCallAfterId = None
def CallAfter(callable, *args, **kw):
"""
Call the specified function after the current and pending event
handlers have been completed. This is also good for making GUI
- method calls from non-GUI threads.
+ method calls from non-GUI threads. Any extra positional or
+ keyword args are passed on to the callable when it is called.
+
+ :see: `wx.FutureCall`
"""
app = wx.GetApp()
- assert app, 'No wxApp created yet'
+ assert app is not None, 'No wx.App created yet'
- global _wxPyCallAfterId
- if _wxPyCallAfterId is None:
- _wxPyCallAfterId = wx.NewEventType()
- app.Connect(-1, -1, _wxPyCallAfterId,
- lambda event: event.callable(*event.args, **event.kw) )
+ if not hasattr(app, "_CallAfterId"):
+ app._CallAfterId = wx.NewEventType()
+ app.Connect(-1, -1, app._CallAfterId,
+ lambda event: event.callable(*event.args, **event.kw) )
evt = wx.PyEvent()
- evt.SetEventType(_wxPyCallAfterId)
+ evt.SetEventType(app._CallAfterId)
evt.callable = callable
evt.args = args
evt.kw = kw
wx.PostEvent(app, evt)
-
#----------------------------------------------------------------------------
class FutureCall:
"""
- A convenience class for wxTimer, that calls the given callable
+ A convenience class for `wx.Timer`, that calls the given callable
object once after the given amount of milliseconds, passing any
positional or keyword args. The return value of the callable is
- availbale after it has been run with the GetResult method.
+ availbale after it has been run with the `GetResult` method.
If you don't need to get the return value or restart the timer
then there is no need to hold a reference to this object. It will
has a reference to self.Notify) but the cycle will be broken when
the timer completes, automatically cleaning up the wx.FutureCall
object.
+
+ :see: `wx.CallAfter`
"""
def __init__(self, millis, callable, *args, **kwargs):
self.millis = millis
self.callable = callable
self.SetArgs(*args, **kwargs)
self.runCount = 0
+ self.running = False
self.hasRun = False
self.result = None
self.timer = None
self.Stop()
self.timer = wx.PyTimer(self.Notify)
self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
+ self.running = True
Restart = Start
"""
if self.callable and getattr(self.callable, 'im_self', True):
self.runCount += 1
+ self.running = False
self.result = self.callable(*self.args, **self.kwargs)
self.hasRun = True
- wx.CallAfter(self.Stop)
+ if not self.running:
+ # if it wasn't restarted, then cleanup
+ wx.CallAfter(self.Stop)
+
+#----------------------------------------------------------------------------
+# Control which items in this module should be documented by epydoc.
+# We allow only classes and functions, which will help reduce the size
+# of the docs by filtering out the zillions of constants, EVT objects,
+# and etc that don't make much sense by themselves, but are instead
+# documented (or will be) as part of the classes/functions/methods
+# where they should be used.
+
+class __DocFilter:
+ """
+ A filter for epydoc that only allows non-Ptr classes and
+ fucntions, in order to reduce the clutter in the API docs.
+ """
+ def __init__(self, globals):
+ self._globals = globals
+
+ def __call__(self, name):
+ import types
+ obj = self._globals.get(name, None)
+ if type(obj) not in [type, types.ClassType, types.FunctionType, types.BuiltinFunctionType]:
+ return False
+ if name.startswith('_') or name.endswith('Ptr') or name.startswith('EVT'):
+ return False
+ return True
+
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
# Import other modules in this package that should show up in the
# "core" wx namespace
-from gdi import *
-from windows import *
-from controls import *
-from misc import *
+from _gdi import *
+from _windows import *
+from _controls import *
+from _misc import *
+
+
+# Fixup the stock objects since they can't be used yet. (They will be
+# restored in wx.PyApp.OnInit.)
+_core_._wxPyFixStockObjects()
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------