]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/_core_ex.py
Added Brian Victor's Patch
[wxWidgets.git] / wxPython / src / _core_ex.py
1 #----------------------------------------------------------------------------
2
3 # Use Python's bool constants if available, make some if not
4 try:
5 True
6 except NameError:
7 __builtins__.True = 1==1
8 __builtins__.False = 1==0
9
10
11
12 # workarounds for bad wxRTTI names
13 __wxPyPtrTypeMap['wxGauge95'] = 'wxGauge'
14 __wxPyPtrTypeMap['wxSlider95'] = 'wxSlider'
15 __wxPyPtrTypeMap['wxStatusBar95'] = 'wxStatusBar'
16
17
18 #----------------------------------------------------------------------------
19 # Load version numbers from __version__... Ensure that major and minor
20 # versions are the same for both wxPython and wxWindows.
21
22 from __version__ import *
23 __version__ = VERSION_STRING
24
25 assert MAJOR_VERSION == _core.MAJOR_VERSION, "wxPython/wxWindows version mismatch"
26 assert MINOR_VERSION == _core.MINOR_VERSION, "wxPython/wxWindows version mismatch"
27 if RELEASE_VERSION != _core.RELEASE_VERSION:
28 import warnings
29 warnings.warn("wxPython/wxWindows release number mismatch")
30
31 #----------------------------------------------------------------------------
32
33 class PyDeadObjectError(AttributeError):
34 pass
35
36
37 class _wxPyDeadObject(object):
38 """
39 Instances of wx objects that are OOR capable will have their __class__
40 changed to this class when the C++ object is deleted. This should help
41 prevent crashes due to referencing a bogus C++ pointer.
42 """
43 reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
44 attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
45
46 def __repr__( self ):
47 if not hasattr(self, "_name"):
48 self._name = "[unknown]"
49 return self.reprStr % self._name
50
51 def __getattr__( self, *args ):
52 if not hasattr(self, "_name"):
53 self._name = "[unknown]"
54 raise PyDeadObjectError( self.attrStr % self._name )
55
56 def __nonzero__(self):
57 return 0
58
59
60 #----------------------------------------------------------------------------
61 _wxPyCallAfterId = None
62
63 def CallAfter(callable, *args, **kw):
64 """
65 Call the specified function after the current and pending event
66 handlers have been completed. This is also good for making GUI
67 method calls from non-GUI threads.
68 """
69 app = wx.GetApp()
70 assert app, 'No wxApp created yet'
71
72 global _wxPyCallAfterId
73 if _wxPyCallAfterId is None:
74 _wxPyCallAfterId = wx.NewEventType()
75 app.Connect(-1, -1, _wxPyCallAfterId,
76 lambda event: event.callable(*event.args, **event.kw) )
77 evt = wx.PyEvent()
78 evt.SetEventType(_wxPyCallAfterId)
79 evt.callable = callable
80 evt.args = args
81 evt.kw = kw
82 wx.PostEvent(app, evt)
83
84
85 #----------------------------------------------------------------------------
86
87
88 class FutureCall:
89 """
90 A convenience class for wxTimer, that calls the given callable
91 object once after the given amount of milliseconds, passing any
92 positional or keyword args. The return value of the callable is
93 availbale after it has been run with the GetResult method.
94
95 If you don't need to get the return value or restart the timer
96 then there is no need to hold a reference to this object. It will
97 hold a reference to itself while the timer is running (the timer
98 has a reference to self.Notify) but the cycle will be broken when
99 the timer completes, automatically cleaning up the wx.FutureCall
100 object.
101 """
102 def __init__(self, millis, callable, *args, **kwargs):
103 self.millis = millis
104 self.callable = callable
105 self.SetArgs(*args, **kwargs)
106 self.runCount = 0
107 self.hasRun = False
108 self.result = None
109 self.timer = None
110 self.Start()
111
112 def __del__(self):
113 self.Stop()
114
115
116 def Start(self, millis=None, *args, **kwargs):
117 """
118 (Re)start the timer
119 """
120 self.hasRun = False
121 if millis is not None:
122 self.millis = millis
123 if args or kwargs:
124 self.SetArgs(*args, **kwargs)
125 self.Stop()
126 self.timer = wx.PyTimer(self.Notify)
127 self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
128 Restart = Start
129
130
131 def Stop(self):
132 """
133 Stop and destroy the timer.
134 """
135 if self.timer is not None:
136 self.timer.Stop()
137 self.timer = None
138
139
140 def GetInterval(self):
141 if self.timer is not None:
142 return self.timer.GetInterval()
143 else:
144 return 0
145
146
147 def IsRunning(self):
148 return self.timer is not None and self.timer.IsRunning()
149
150
151 def SetArgs(self, *args, **kwargs):
152 """
153 (Re)set the args passed to the callable object. This is
154 useful in conjunction with Restart if you want to schedule a
155 new call to the same callable object but with different
156 parameters.
157 """
158 self.args = args
159 self.kwargs = kwargs
160
161
162 def HasRun(self):
163 return self.hasRun
164
165 def GetResult(self):
166 return self.result
167
168 def Notify(self):
169 """
170 The timer has expired so call the callable.
171 """
172 if self.callable and getattr(self.callable, 'im_self', True):
173 self.runCount += 1
174 self.result = self.callable(*self.args, **self.kwargs)
175 self.hasRun = True
176 wx.CallAfter(self.Stop)
177
178
179 #----------------------------------------------------------------------------
180 #----------------------------------------------------------------------------
181
182 # Import other modules in this package that should show up in the
183 # "core" wx namespace
184 from gdi import *
185 from windows import *
186 from controls import *
187 from misc import *
188
189 #----------------------------------------------------------------------------
190 #----------------------------------------------------------------------------