]>
Commit | Line | Data |
---|---|---|
8fa876ca RD |
1 | import time |
2 | import wx | |
66065839 RD |
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 = """\ | |
04f99266 | 28 | wx.CallLater is a convenience class for wx.Timer. You just |
66065839 | 29 | specify the timeout in milliseconds and a callable object, along |
04f99266 VZ |
30 | with any args or keyword args you would like to be passed to your |
31 | callable, and wx.CallLater takes care of the rest. If you don't | |
66065839 RD |
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 | """ | |
cf694132 | 41 | |
cf694132 | 42 | |
66065839 RD |
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 | """ | |
cf694132 | 49 | |
cf694132 | 50 | |
66065839 | 51 | class TestPanel(sp.ScrolledPanel): |
cf694132 | 52 | def __init__(self, parent, log): |
e6157a69 | 53 | self.log = log |
66065839 RD |
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 | ||
04f99266 | 79 | t2b1 = wx.Button(self, -1, "wx.CallLater") |
66065839 RD |
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) | |
cf694132 | 110 | |
66065839 RD |
111 | fgs.Add(t2b1) |
112 | fgs.Add(t2b2) | |
113 | fgs.Add(t2st) | |
e6157a69 | 114 | |
66065839 RD |
115 | fgs.Add(t3b1) |
116 | fgs.Add(t3b2) | |
117 | fgs.Add(t3st) | |
b96c7a38 | 118 | |
66065839 RD |
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 | ||
cf694132 | 127 | |
66065839 RD |
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() | |
cf694132 | 137 | |
66065839 RD |
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() | |
e6157a69 | 143 | |
66065839 RD |
144 | def OnTest1Timer(self, evt): |
145 | self.log.write("got EVT_TIMER event\n") | |
146 | ||
cf694132 | 147 | |
b96c7a38 | 148 | |
04f99266 | 149 | # Test 2 shows how to use the wx.CallLater class. |
66065839 RD |
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 | |
04f99266 | 156 | self.t2 = wx.CallLater(1000, self.OnTest2Timer, |
66065839 | 157 | 'a', 'b', 'c', one=1, two=2) |
04f99266 | 158 | self.log.write("CallLater scheduled\n") |
66065839 RD |
159 | self.t2b2.Enable() |
160 | ||
161 | def OnTest2Stop(self, evt): | |
162 | self.t2.Stop() | |
04f99266 | 163 | self.log.write("CallLater stopped, last return value was: %s\n" % |
66065839 RD |
164 | repr(self.t2.GetResult())) |
165 | del self.t2 | |
166 | self.t2b2.Disable() | |
167 | ||
168 | def OnTest2Timer(self, *args, **kw): | |
04f99266 | 169 | self.log.write("CallLater called with args=%s, kwargs=%s\n" % (args, kw)) |
66065839 RD |
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): | |
5cd7ab8d | 232 | self.log.write("got NotifyTimer event\n") |
66065839 RD |
233 | |
234 | ||
235 | ||
236 | #---------------------------------------------------------------------- | |
cf694132 RD |
237 | |
238 | def runTest(frame, nb, log): | |
66065839 | 239 | win = TestPanel(nb, log) |
cf694132 RD |
240 | return win |
241 | ||
cf694132 | 242 | |
66065839 | 243 | #---------------------------------------------------------------------- |
cf694132 | 244 | |
66065839 RD |
245 | overview = """<html><body> |
246 | <h2><center>wx.Timer</center></h2> | |
cf694132 | 247 | |
66065839 RD |
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. | |
cf694132 | 254 | |
66065839 | 255 | </body></html> |
cf694132 | 256 | """ |
68d92db3 RD |
257 | |
258 | ||
259 | ||
1fded56b RD |
260 | if __name__ == '__main__': |
261 | import sys,os | |
262 | import run | |
8eca4fef | 263 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) |
66065839 RD |
264 | |
265 | ||
266 | ||
267 |