]>
Commit | Line | Data |
---|---|---|
1 | import time | |
2 | import wx | |
3 | import wx.lib.scrolledpanel as sp | |
4 | ||
5 | #---------------------------------------------------------------------- | |
6 | ||
7 | ||
8 | header = """\ | |
9 | This demo shows the various ways that wx.Timers can be used in your code. Just | |
10 | select one of the buttons in the left column to start a timer in the indicated way, | |
11 | and watch the log window below for messages printed when the timer event or callback | |
12 | happens. Clicking the corresponding button on the right will stop that timer. Since | |
13 | timers are not owned by any other wx object you should hold on to a reference to the | |
14 | timer until you are completely finished with it. """ | |
15 | ||
16 | doc1 = """\ | |
17 | Binding an event handler to the wx.EVT_TIMER event is the | |
18 | prefered way to use the wx.Timer class directly. It makes | |
19 | handling timer events work just like normal window events. You | |
20 | just need to specify the window that is to receive the event in | |
21 | the wx.Timer constructor. If that window needs to be able to | |
22 | receive events from more than one timer then you can optionally | |
23 | specify an ID for the timer and the event binding. | |
24 | """ | |
25 | ||
26 | ||
27 | doc2 = """\ | |
28 | wx.FutureCall is a convenience class for wx.Timer. You just | |
29 | specify the timeout in milliseconds and a callable object, along | |
30 | with any ard or keyword arg you woudl like to be passed to your | |
31 | callable, and wx.FutureCall takes care of the rest. If you don't | |
32 | need to get the return value of the callable or to restart the | |
33 | timer then there is no need to hold a reference to this object. | |
34 | """ | |
35 | ||
36 | ||
37 | doc3 = """\ | |
38 | If you derive a class from wx.Timer and give it a Notify method | |
39 | then it will be called when the timer expires. | |
40 | """ | |
41 | ||
42 | ||
43 | doc4 = """\ | |
44 | wx.PyTimer is the old way (a kludge that goes back all the way to | |
45 | the first version of wxPython) to bind a timer directly to a | |
46 | callable. You should migrate any code that uses this method to | |
47 | use EVT_TIMER instead as this may be deprecated in the future. | |
48 | """ | |
49 | ||
50 | ||
51 | class TestPanel(sp.ScrolledPanel): | |
52 | def __init__(self, parent, log): | |
53 | self.log = log | |
54 | sp.ScrolledPanel.__init__(self, parent, -1) | |
55 | ||
56 | outsideSizer = wx.BoxSizer(wx.VERTICAL) | |
57 | ||
58 | text = wx.StaticText(self, -1, "wx.Timer", style=wx.ALIGN_CENTRE) | |
59 | text.SetFont(wx.Font(24, wx.SWISS, wx.NORMAL, wx.BOLD, False)) | |
60 | text.SetSize(text.GetBestSize()) | |
61 | text.SetForegroundColour(wx.BLUE) | |
62 | outsideSizer.Add(text, 0, wx.EXPAND|wx.ALL, 5) | |
63 | outsideSizer.Add(wx.StaticText(self, -1, header), 0, wx.ALIGN_CENTER|wx.ALL, 5) | |
64 | outsideSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND) | |
65 | outsideSizer.Add((20,20)) | |
66 | ||
67 | ||
68 | t1b1 = wx.Button(self, -1, "EVT_TIMER") | |
69 | t1b2 = wx.Button(self, -1, "stop timer") | |
70 | t1st = wx.StaticText(self, -1, doc1) | |
71 | t1b2.Disable() | |
72 | self.Bind(wx.EVT_BUTTON, self.OnTest1Start, t1b1) | |
73 | self.Bind(wx.EVT_BUTTON, self.OnTest1Stop, t1b2) | |
74 | ||
75 | # Bind all EVT_TIMER events to self.OnTest1Timer | |
76 | self.Bind(wx.EVT_TIMER, self.OnTest1Timer) | |
77 | ||
78 | ||
79 | t2b1 = wx.Button(self, -1, "wx.FutureCall") | |
80 | t2b2 = wx.Button(self, -1, "stop timer") | |
81 | t2st = wx.StaticText(self, -1, doc2) | |
82 | t2b2.Disable() | |
83 | self.Bind(wx.EVT_BUTTON, self.OnTest2Start, t2b1) | |
84 | self.Bind(wx.EVT_BUTTON, self.OnTest2Stop, t2b2) | |
85 | ||
86 | t3b1 = wx.Button(self, -1, "self.Notify") | |
87 | t3b2 = wx.Button(self, -1, "stop timer") | |
88 | t3st = wx.StaticText(self, -1, doc3) | |
89 | t3b2.Disable() | |
90 | self.Bind(wx.EVT_BUTTON, self.OnTest3Start, t3b1) | |
91 | self.Bind(wx.EVT_BUTTON, self.OnTest3Stop, t3b2) | |
92 | ||
93 | t4b1 = wx.Button(self, -1, "wx.PyTimer") | |
94 | t4b2 = wx.Button(self, -1, "stop timer") | |
95 | t4st = wx.StaticText(self, -1, doc4) | |
96 | t4b2.Disable() | |
97 | self.Bind(wx.EVT_BUTTON, self.OnTest4Start, t4b1) | |
98 | self.Bind(wx.EVT_BUTTON, self.OnTest4Stop, t4b2) | |
99 | ||
100 | ||
101 | self.t1b2 = t1b2 | |
102 | self.t2b2 = t2b2 | |
103 | self.t3b2 = t3b2 | |
104 | self.t4b2 = t4b2 | |
105 | ||
106 | fgs = wx.FlexGridSizer(cols=3, hgap=10, vgap=10) | |
107 | fgs.Add(t1b1) | |
108 | fgs.Add(t1b2) | |
109 | fgs.Add(t1st) | |
110 | ||
111 | fgs.Add(t2b1) | |
112 | fgs.Add(t2b2) | |
113 | fgs.Add(t2st) | |
114 | ||
115 | fgs.Add(t3b1) | |
116 | fgs.Add(t3b2) | |
117 | fgs.Add(t3st) | |
118 | ||
119 | fgs.Add(t4b1) | |
120 | fgs.Add(t4b2) | |
121 | fgs.Add(t4st) | |
122 | ||
123 | outsideSizer.Add(fgs, 0, wx.ALIGN_CENTER|wx.ALL, 10) | |
124 | self.SetSizer(outsideSizer) | |
125 | self.SetupScrolling() | |
126 | ||
127 | ||
128 | # Test 1 shows how to use a timer to generate EVT_TIMER | |
129 | # events, by passing self to the wx.Timer constructor. The | |
130 | # event is bound above to the OnTest1Timer method. | |
131 | ||
132 | def OnTest1Start(self, evt): | |
133 | self.t1 = wx.Timer(self) | |
134 | self.t1.Start(1000) | |
135 | self.log.write("EVT_TIMER timer started\n") | |
136 | self.t1b2.Enable() | |
137 | ||
138 | def OnTest1Stop(self, evt): | |
139 | self.t1.Stop() | |
140 | self.log.write("EVT_TIMER timer stoped\n") | |
141 | del self.t1 | |
142 | self.t1b2.Disable() | |
143 | ||
144 | def OnTest1Timer(self, evt): | |
145 | self.log.write("got EVT_TIMER event\n") | |
146 | ||
147 | ||
148 | ||
149 | # Test 2 shows how to use the wx.FutureCall class. | |
150 | ||
151 | def OnTest2Start(self, evt): | |
152 | # Call OnTest2Timer one second in the future, passing some | |
153 | # optional arbitrary args. There is no need to hold a | |
154 | # reference to this one, unless we want to manipulate or query | |
155 | # it later like we do in the two methods below | |
156 | self.t2 = wx.FutureCall(1000, self.OnTest2Timer, | |
157 | 'a', 'b', 'c', one=1, two=2) | |
158 | self.log.write("FutureCall scheduled\n") | |
159 | self.t2b2.Enable() | |
160 | ||
161 | def OnTest2Stop(self, evt): | |
162 | self.t2.Stop() | |
163 | self.log.write("FutureCall stopped, last return value was: %s\n" % | |
164 | repr(self.t2.GetResult())) | |
165 | del self.t2 | |
166 | self.t2b2.Disable() | |
167 | ||
168 | def OnTest2Timer(self, *args, **kw): | |
169 | self.log.write("FutureCall called with args=%s, kwargs=%s\n" % (args, kw)) | |
170 | ||
171 | # Normally a FutureCall is one-shot, but we can make it | |
172 | # recurring just by calling Restart. We can even use a | |
173 | # different timeout or pass differnt args this time. | |
174 | self.t2.Restart(1500, "restarted") | |
175 | ||
176 | # The return value of this function is saved and can be | |
177 | # retrived later. See OnTest2Stop above. | |
178 | return "This is my return value" | |
179 | ||
180 | ||
181 | ||
182 | # Test 3 shows how to use a class derived from wx.Timer. See | |
183 | # also the NotifyTimer class below. | |
184 | ||
185 | def OnTest3Start(self, evt): | |
186 | self.t3 = NotifyTimer(self.log) | |
187 | self.t3.Start(1000) | |
188 | self.log.write("NotifyTimer timer started\n") | |
189 | self.t3b2.Enable() | |
190 | ||
191 | def OnTest3Stop(self, evt): | |
192 | self.t3.Stop() | |
193 | self.log.write("NotifyTimer timer stoped\n") | |
194 | del self.t3 | |
195 | self.t3b2.Disable() | |
196 | ||
197 | ||
198 | ||
199 | # Test 4 shows the old way (a kludge that goes back all the | |
200 | # way to the first version of wxPython) to bind a timer | |
201 | # directly to a callable. You should migrate any code that | |
202 | # uses this method to use EVT_TIMER instead as this may be | |
203 | # deprecated in the future. | |
204 | def OnTest4Start(self, evt): | |
205 | self.t4 = wx.PyTimer(self.OnTest4Timer) | |
206 | self.t4.Start(1000) | |
207 | self.log.write("wx.PyTimer timer started\n") | |
208 | self.t4b2.Enable() | |
209 | ||
210 | def OnTest4Stop(self, evt): | |
211 | self.t4.Stop() | |
212 | self.log.write("wx.PyTimer timer stoped\n") | |
213 | del self.t4 | |
214 | self.t4b2.Disable() | |
215 | ||
216 | def OnTest4Timer(self): | |
217 | self.log.write("got wx.PyTimer event\n") | |
218 | ||
219 | ||
220 | ||
221 | #---------------------------------------------------------------------- | |
222 | ||
223 | ||
224 | # When deriving from wx.Timer you must provide a Notify method | |
225 | # that will be called when the timer expires. | |
226 | class NotifyTimer(wx.Timer): | |
227 | def __init__(self, log): | |
228 | wx.Timer.__init__(self) | |
229 | self.log = log | |
230 | ||
231 | def Notify(self): | |
232 | log.write("got NotifyTimer event\n") | |
233 | ||
234 | ||
235 | ||
236 | #---------------------------------------------------------------------- | |
237 | ||
238 | def runTest(frame, nb, log): | |
239 | win = TestPanel(nb, log) | |
240 | return win | |
241 | ||
242 | ||
243 | #---------------------------------------------------------------------- | |
244 | ||
245 | overview = """<html><body> | |
246 | <h2><center>wx.Timer</center></h2> | |
247 | ||
248 | The wx.Timer class allows you to execute code at specified intervals | |
249 | from within the wxPython event loop. Timers can be one-shot or | |
250 | repeating. This demo shows the principle method of using a timer | |
251 | (with events) as well as the convenient wx.FutureCall class. Also | |
252 | there are two other usage patterns shown here that have been preserved | |
253 | for backwards compatibility. | |
254 | ||
255 | </body></html> | |
256 | """ | |
257 | ||
258 | ||
259 | ||
260 | if __name__ == '__main__': | |
261 | import sys,os | |
262 | import run | |
263 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) | |
264 | ||
265 | ||
266 | ||
267 |