]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/KeyEvents.py
Change event names to clarify that they are only fired by button clicks, and note...
[wxWidgets.git] / wxPython / demo / KeyEvents.py
1
2 import wx
3 import wx.lib.mixins.listctrl as listmix
4
5 #----------------------------------------------------------------------
6
7 keyMap = {
8 wx.WXK_BACK : "WXK_BACK",
9 wx.WXK_TAB : "WXK_TAB",
10 wx.WXK_RETURN : "WXK_RETURN",
11 wx.WXK_ESCAPE : "WXK_ESCAPE",
12 wx.WXK_SPACE : "WXK_SPACE",
13 wx.WXK_DELETE : "WXK_DELETE",
14 wx.WXK_START : "WXK_START",
15 wx.WXK_LBUTTON : "WXK_LBUTTON",
16 wx.WXK_RBUTTON : "WXK_RBUTTON",
17 wx.WXK_CANCEL : "WXK_CANCEL",
18 wx.WXK_MBUTTON : "WXK_MBUTTON",
19 wx.WXK_CLEAR : "WXK_CLEAR",
20 wx.WXK_SHIFT : "WXK_SHIFT",
21 wx.WXK_ALT : "WXK_ALT",
22 wx.WXK_CONTROL : "WXK_CONTROL",
23 wx.WXK_MENU : "WXK_MENU",
24 wx.WXK_PAUSE : "WXK_PAUSE",
25 wx.WXK_CAPITAL : "WXK_CAPITAL",
26 #wx.WXK_PRIOR : "WXK_PRIOR",
27 #wx.WXK_NEXT : "WXK_NEXT",
28 wx.WXK_END : "WXK_END",
29 wx.WXK_HOME : "WXK_HOME",
30 wx.WXK_LEFT : "WXK_LEFT",
31 wx.WXK_UP : "WXK_UP",
32 wx.WXK_RIGHT : "WXK_RIGHT",
33 wx.WXK_DOWN : "WXK_DOWN",
34 wx.WXK_SELECT : "WXK_SELECT",
35 wx.WXK_PRINT : "WXK_PRINT",
36 wx.WXK_EXECUTE : "WXK_EXECUTE",
37 wx.WXK_SNAPSHOT : "WXK_SNAPSHOT",
38 wx.WXK_INSERT : "WXK_INSERT",
39 wx.WXK_HELP : "WXK_HELP",
40 wx.WXK_NUMPAD0 : "WXK_NUMPAD0",
41 wx.WXK_NUMPAD1 : "WXK_NUMPAD1",
42 wx.WXK_NUMPAD2 : "WXK_NUMPAD2",
43 wx.WXK_NUMPAD3 : "WXK_NUMPAD3",
44 wx.WXK_NUMPAD4 : "WXK_NUMPAD4",
45 wx.WXK_NUMPAD5 : "WXK_NUMPAD5",
46 wx.WXK_NUMPAD6 : "WXK_NUMPAD6",
47 wx.WXK_NUMPAD7 : "WXK_NUMPAD7",
48 wx.WXK_NUMPAD8 : "WXK_NUMPAD8",
49 wx.WXK_NUMPAD9 : "WXK_NUMPAD9",
50 wx.WXK_MULTIPLY : "WXK_MULTIPLY",
51 wx.WXK_ADD : "WXK_ADD",
52 wx.WXK_SEPARATOR : "WXK_SEPARATOR",
53 wx.WXK_SUBTRACT : "WXK_SUBTRACT",
54 wx.WXK_DECIMAL : "WXK_DECIMAL",
55 wx.WXK_DIVIDE : "WXK_DIVIDE",
56 wx.WXK_F1 : "WXK_F1",
57 wx.WXK_F2 : "WXK_F2",
58 wx.WXK_F3 : "WXK_F3",
59 wx.WXK_F4 : "WXK_F4",
60 wx.WXK_F5 : "WXK_F5",
61 wx.WXK_F6 : "WXK_F6",
62 wx.WXK_F7 : "WXK_F7",
63 wx.WXK_F8 : "WXK_F8",
64 wx.WXK_F9 : "WXK_F9",
65 wx.WXK_F10 : "WXK_F10",
66 wx.WXK_F11 : "WXK_F11",
67 wx.WXK_F12 : "WXK_F12",
68 wx.WXK_F13 : "WXK_F13",
69 wx.WXK_F14 : "WXK_F14",
70 wx.WXK_F15 : "WXK_F15",
71 wx.WXK_F16 : "WXK_F16",
72 wx.WXK_F17 : "WXK_F17",
73 wx.WXK_F18 : "WXK_F18",
74 wx.WXK_F19 : "WXK_F19",
75 wx.WXK_F20 : "WXK_F20",
76 wx.WXK_F21 : "WXK_F21",
77 wx.WXK_F22 : "WXK_F22",
78 wx.WXK_F23 : "WXK_F23",
79 wx.WXK_F24 : "WXK_F24",
80 wx.WXK_NUMLOCK : "WXK_NUMLOCK",
81 wx.WXK_SCROLL : "WXK_SCROLL",
82 wx.WXK_PAGEUP : "WXK_PAGEUP",
83 wx.WXK_PAGEDOWN : "WXK_PAGEDOWN",
84 wx.WXK_NUMPAD_SPACE : "WXK_NUMPAD_SPACE",
85 wx.WXK_NUMPAD_TAB : "WXK_NUMPAD_TAB",
86 wx.WXK_NUMPAD_ENTER : "WXK_NUMPAD_ENTER",
87 wx.WXK_NUMPAD_F1 : "WXK_NUMPAD_F1",
88 wx.WXK_NUMPAD_F2 : "WXK_NUMPAD_F2",
89 wx.WXK_NUMPAD_F3 : "WXK_NUMPAD_F3",
90 wx.WXK_NUMPAD_F4 : "WXK_NUMPAD_F4",
91 wx.WXK_NUMPAD_HOME : "WXK_NUMPAD_HOME",
92 wx.WXK_NUMPAD_LEFT : "WXK_NUMPAD_LEFT",
93 wx.WXK_NUMPAD_UP : "WXK_NUMPAD_UP",
94 wx.WXK_NUMPAD_RIGHT : "WXK_NUMPAD_RIGHT",
95 wx.WXK_NUMPAD_DOWN : "WXK_NUMPAD_DOWN",
96 #wx.WXK_NUMPAD_PRIOR : "WXK_NUMPAD_PRIOR",
97 wx.WXK_NUMPAD_PAGEUP : "WXK_NUMPAD_PAGEUP",
98 #wx.WXK_NUMPAD_NEXT : "WXK_NUMPAD_NEXT",
99 wx.WXK_NUMPAD_PAGEDOWN : "WXK_NUMPAD_PAGEDOWN",
100 wx.WXK_NUMPAD_END : "WXK_NUMPAD_END",
101 wx.WXK_NUMPAD_BEGIN : "WXK_NUMPAD_BEGIN",
102 wx.WXK_NUMPAD_INSERT : "WXK_NUMPAD_INSERT",
103 wx.WXK_NUMPAD_DELETE : "WXK_NUMPAD_DELETE",
104 wx.WXK_NUMPAD_EQUAL : "WXK_NUMPAD_EQUAL",
105 wx.WXK_NUMPAD_MULTIPLY : "WXK_NUMPAD_MULTIPLY",
106 wx.WXK_NUMPAD_ADD : "WXK_NUMPAD_ADD",
107 wx.WXK_NUMPAD_SEPARATOR : "WXK_NUMPAD_SEPARATOR",
108 wx.WXK_NUMPAD_SUBTRACT : "WXK_NUMPAD_SUBTRACT",
109 wx.WXK_NUMPAD_DECIMAL : "WXK_NUMPAD_DECIMAL",
110 wx.WXK_NUMPAD_DIVIDE : "WXK_NUMPAD_DIVIDE",
111 }
112
113
114 #----------------------------------------------------------------------
115
116 class KeySink(wx.Window):
117 def __init__(self, parent):
118 wx.Window.__init__(self, parent, -1, style=wx.WANTS_CHARS
119 #| wx.RAISED_BORDER
120 #| wx.SUNKEN_BORDER
121 , name="sink")
122
123 self.SetBackgroundColour(wx.BLUE)
124 self.haveFocus = False
125 self.callSkip = True
126 self.logKeyDn = True
127 self.logKeyUp = True
128 self.logChar = True
129
130 self.Bind(wx.EVT_PAINT, self.OnPaint)
131 self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
132 self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
133 self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
134
135 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
136 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
137 self.Bind(wx.EVT_CHAR, self.OnChar)
138
139
140 def SetCallSkip(self, skip):
141 self.callSkip = skip
142
143 def SetLogKeyUp(self, val):
144 self.logKeyUp = val
145
146 def SetLogKeyDn(self, val):
147 self.logKeyDn = val
148
149 def SetLogChar(self, val):
150 self.logChar = val
151
152
153 def OnPaint(self, evt):
154 dc = wx.PaintDC(self)
155 rect = self.GetClientRect()
156 dc.SetTextForeground(wx.WHITE)
157 dc.DrawLabel("Click here and then press some keys",
158 rect, wx.ALIGN_CENTER | wx.ALIGN_TOP)
159 if self.haveFocus:
160 dc.SetTextForeground(wx.GREEN)
161 dc.DrawLabel("Have Focus", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
162 else:
163 dc.SetTextForeground(wx.RED)
164 dc.DrawLabel("Need Focus!", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
165
166
167 def OnSetFocus(self, evt):
168 self.haveFocus = True
169 self.Refresh()
170
171 def OnKillFocus(self, evt):
172 self.haveFocus = False
173 self.Refresh()
174
175 def OnMouse(self, evt):
176 if evt.ButtonDown():
177 self.SetFocus()
178
179
180 def OnKeyDown(self, evt):
181 if self.logKeyDn:
182 self.GetParent().keylog.LogKeyEvent("KeyDown", evt)
183 if self.callSkip:
184 evt.Skip()
185
186 def OnKeyUp(self, evt):
187 if self.logKeyUp:
188 self.GetParent().keylog.LogKeyEvent("KeyUp", evt)
189 if self.callSkip:
190 evt.Skip()
191
192 def OnChar(self, evt):
193 if self.logChar:
194 self.GetParent().keylog.LogKeyEvent("Char", evt)
195
196
197 #----------------------------------------------------------------------
198
199 class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
200 colHeaders = [ "Event Type",
201 "Key Name",
202 "Key Code",
203 "Modifiers",
204 "Unicode",
205 "RawKeyCode",
206 "RawKeyFlags",
207 ]
208
209 def __init__(self, parent):
210 wx.ListCtrl.__init__(self, parent, -1,
211 style = wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES)
212 listmix.ListCtrlAutoWidthMixin.__init__(self)
213
214 for idx, header in enumerate(self.colHeaders):
215 self.InsertColumn(idx, header)
216 idx += 1
217 self.InsertColumn(idx, "")
218
219 for x in range(idx):
220 self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
221
222 self.SetColumnWidth(1, 125)
223
224
225 def LogKeyEvent(self, evType, evt):
226 keycode = evt.GetKeyCode()
227 keyname = keyMap.get(keycode, None)
228 if keyname is None:
229 if "unicode" in wx.PlatformInfo:
230 keycode = evt.GetUnicodeKey()
231 if keycode <= 127:
232 keycode = evt.GetKeyCode()
233 keyname = "\"" + unichr(evt.GetUnicodeKey()) + "\""
234 if keycode < 27:
235 keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
236
237 elif keycode < 256:
238 if keycode == 0:
239 keyname = "NUL"
240 elif keycode < 27:
241 keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
242 else:
243 keyname = "\"%s\"" % chr(keycode)
244 else:
245 keyname = "unknown (%s)" % keycode
246
247 modifiers = ""
248 for mod, ch in [(evt.ControlDown(), 'C'),
249 (evt.AltDown(), 'A'),
250 (evt.ShiftDown(), 'S'),
251 (evt.MetaDown(), 'M')]:
252 if mod:
253 modifiers += ch
254 else:
255 modifiers += '-'
256
257 id = self.InsertStringItem(self.GetItemCount(), evType)
258 self.SetStringItem(id, 1, keyname)
259 self.SetStringItem(id, 2, str(keycode))
260 self.SetStringItem(id, 3, modifiers)
261 self.SetStringItem(id, 4, str(evt.GetUnicodeKey()))
262 self.SetStringItem(id, 5, str(evt.GetRawKeyCode()))
263 self.SetStringItem(id, 6, str(evt.GetRawKeyFlags()))
264
265 #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags()))
266
267 self.EnsureVisible(id)
268
269
270 def ClearLog(self):
271 self.DeleteAllItems()
272
273 def CopyLog(self):
274 # build a newline and tab delimited string to put into the clipboard
275 if "unicode" in wx.PlatformInfo:
276 st = u""
277 else:
278 st = ""
279 for h in self.colHeaders:
280 st += h + "\t"
281 st += "\n"
282
283 for idx in range(self.GetItemCount()):
284 for col in range(self.GetColumnCount()):
285 item = self.GetItem(idx, col)
286 st += item.GetText() + "\t"
287 st += "\n"
288
289 data = wx.TextDataObject()
290 data.SetText(st)
291 if wx.TheClipboard.Open():
292 wx.TheClipboard.SetData(data)
293 wx.TheClipboard.Close()
294 else:
295 wx.MessageBox("Unable to open the clipboard", "Error")
296
297
298
299
300 #----------------------------------------------------------------------
301
302
303 class TestPanel(wx.Panel):
304 def __init__(self, parent, log):
305 self.log = log
306 wx.Panel.__init__(self, parent, -1, style=0)
307 self.keysink = KeySink(self)
308 self.keysink.SetMinSize((100, 65))
309 self.keylog = KeyLog(self)
310
311 btn = wx.Button(self, -1, "Clear", style=wx.BU_EXACTFIT)
312 self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn)
313 btn.SetToolTipString(
314 "Clear the items from the log window")
315
316 btn2 = wx.Button(self, -1, "Copy", style=wx.BU_EXACTFIT)
317 self.Bind(wx.EVT_BUTTON, self.OnCopyBtn, btn2)
318 btn2.SetToolTipString(
319 "Copy the contents of the log window to the clipboard")
320
321 cb1 = wx.CheckBox(self, -1, "Call evt.Skip in Key* events")
322 self.Bind(wx.EVT_CHECKBOX, self.OnSkipCB, cb1)
323 cb1.SetValue(True)
324
325 cb2 = wx.CheckBox(self, -1, "KEY_UP")
326 self.Bind(wx.EVT_CHECKBOX, self.OnKeyUpCB, cb2)
327 cb2.SetValue(True)
328
329 cb3 = wx.CheckBox(self, -1, "KEY_DOWN")
330 self.Bind(wx.EVT_CHECKBOX, self.OnKeyDnCB, cb3)
331 cb3.SetValue(True)
332
333 cb4 = wx.CheckBox(self, -1, "CHAR")
334 self.Bind(wx.EVT_CHECKBOX, self.OnCharCB, cb4)
335 cb4.SetValue(True)
336
337 buttons = wx.BoxSizer(wx.HORIZONTAL)
338 buttons.Add(btn, 0, wx.ALL, 4)
339 buttons.Add(btn2, 0, wx.ALL, 4)
340 buttons.Add(cb1, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 6)
341 buttons.Add(cb2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
342 buttons.Add(cb3, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
343 buttons.Add(cb4, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
344
345 sizer = wx.BoxSizer(wx.VERTICAL)
346 sizer.Add(self.keysink, 0, wx.GROW)
347 sizer.Add(buttons)
348 sizer.Add(self.keylog, 1, wx.GROW)
349
350 self.SetSizer(sizer)
351
352
353 def OnClearBtn(self, evt):
354 self.keylog.ClearLog()
355
356 def OnCopyBtn(self, evt):
357 self.keylog.CopyLog()
358
359 def OnSkipCB(self, evt):
360 self.keysink.SetCallSkip(evt.GetInt())
361
362 def OnKeyUpCB(self, evt):
363 self.keysink.SetLogKeyUp(evt.GetInt())
364
365 def OnKeyDnCB(self, evt):
366 self.keysink.SetLogKeyDn(evt.GetInt())
367
368 def OnCharCB(self, evt):
369 self.keysink.SetLogChar(evt.GetInt())
370
371
372 #----------------------------------------------------------------------
373
374 def runTest(frame, nb, log):
375 win = TestPanel(nb, log)
376 return win
377
378 #----------------------------------------------------------------------
379
380
381
382 overview = """<html><body>
383 <h2><center>wxKeyEvents</center></h2>
384
385 This demo simply catches all key events and prints info about them.
386 It is meant to be used as a compatibility test for cross platform work.
387
388 </body></html>
389 """
390
391
392
393 if __name__ == '__main__':
394 import sys,os
395 import run
396 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
397