| 1 | |
| 2 | from wxPython.wx import * |
| 3 | |
| 4 | #---------------------------------------------------------------------- |
| 5 | |
| 6 | keyMap = { |
| 7 | WXK_BACK : "WXK_BACK", |
| 8 | WXK_TAB : "WXK_TAB", |
| 9 | WXK_RETURN : "WXK_RETURN", |
| 10 | WXK_ESCAPE : "WXK_ESCAPE", |
| 11 | WXK_SPACE : "WXK_SPACE", |
| 12 | WXK_DELETE : "WXK_DELETE", |
| 13 | WXK_START : "WXK_START", |
| 14 | WXK_LBUTTON : "WXK_LBUTTON", |
| 15 | WXK_RBUTTON : "WXK_RBUTTON", |
| 16 | WXK_CANCEL : "WXK_CANCEL", |
| 17 | WXK_MBUTTON : "WXK_MBUTTON", |
| 18 | WXK_CLEAR : "WXK_CLEAR", |
| 19 | WXK_SHIFT : "WXK_SHIFT", |
| 20 | WXK_ALT : "WXK_ALT", |
| 21 | WXK_CONTROL : "WXK_CONTROL", |
| 22 | WXK_MENU : "WXK_MENU", |
| 23 | WXK_PAUSE : "WXK_PAUSE", |
| 24 | WXK_CAPITAL : "WXK_CAPITAL", |
| 25 | WXK_PRIOR : "WXK_PRIOR", |
| 26 | WXK_NEXT : "WXK_NEXT", |
| 27 | WXK_END : "WXK_END", |
| 28 | WXK_HOME : "WXK_HOME", |
| 29 | WXK_LEFT : "WXK_LEFT", |
| 30 | WXK_UP : "WXK_UP", |
| 31 | WXK_RIGHT : "WXK_RIGHT", |
| 32 | WXK_DOWN : "WXK_DOWN", |
| 33 | WXK_SELECT : "WXK_SELECT", |
| 34 | WXK_PRINT : "WXK_PRINT", |
| 35 | WXK_EXECUTE : "WXK_EXECUTE", |
| 36 | WXK_SNAPSHOT : "WXK_SNAPSHOT", |
| 37 | WXK_INSERT : "WXK_INSERT", |
| 38 | WXK_HELP : "WXK_HELP", |
| 39 | WXK_NUMPAD0 : "WXK_NUMPAD0", |
| 40 | WXK_NUMPAD1 : "WXK_NUMPAD1", |
| 41 | WXK_NUMPAD2 : "WXK_NUMPAD2", |
| 42 | WXK_NUMPAD3 : "WXK_NUMPAD3", |
| 43 | WXK_NUMPAD4 : "WXK_NUMPAD4", |
| 44 | WXK_NUMPAD5 : "WXK_NUMPAD5", |
| 45 | WXK_NUMPAD6 : "WXK_NUMPAD6", |
| 46 | WXK_NUMPAD7 : "WXK_NUMPAD7", |
| 47 | WXK_NUMPAD8 : "WXK_NUMPAD8", |
| 48 | WXK_NUMPAD9 : "WXK_NUMPAD9", |
| 49 | WXK_MULTIPLY : "WXK_MULTIPLY", |
| 50 | WXK_ADD : "WXK_ADD", |
| 51 | WXK_SEPARATOR : "WXK_SEPARATOR", |
| 52 | WXK_SUBTRACT : "WXK_SUBTRACT", |
| 53 | WXK_DECIMAL : "WXK_DECIMAL", |
| 54 | WXK_DIVIDE : "WXK_DIVIDE", |
| 55 | WXK_F1 : "WXK_F1", |
| 56 | WXK_F2 : "WXK_F2", |
| 57 | WXK_F3 : "WXK_F3", |
| 58 | WXK_F4 : "WXK_F4", |
| 59 | WXK_F5 : "WXK_F5", |
| 60 | WXK_F6 : "WXK_F6", |
| 61 | WXK_F7 : "WXK_F7", |
| 62 | WXK_F8 : "WXK_F8", |
| 63 | WXK_F9 : "WXK_F9", |
| 64 | WXK_F10 : "WXK_F10", |
| 65 | WXK_F11 : "WXK_F11", |
| 66 | WXK_F12 : "WXK_F12", |
| 67 | WXK_F13 : "WXK_F13", |
| 68 | WXK_F14 : "WXK_F14", |
| 69 | WXK_F15 : "WXK_F15", |
| 70 | WXK_F16 : "WXK_F16", |
| 71 | WXK_F17 : "WXK_F17", |
| 72 | WXK_F18 : "WXK_F18", |
| 73 | WXK_F19 : "WXK_F19", |
| 74 | WXK_F20 : "WXK_F20", |
| 75 | WXK_F21 : "WXK_F21", |
| 76 | WXK_F22 : "WXK_F22", |
| 77 | WXK_F23 : "WXK_F23", |
| 78 | WXK_F24 : "WXK_F24", |
| 79 | WXK_NUMLOCK : "WXK_NUMLOCK", |
| 80 | WXK_SCROLL : "WXK_SCROLL", |
| 81 | WXK_PAGEUP : "WXK_PAGEUP", |
| 82 | WXK_PAGEDOWN : "WXK_PAGEDOWN", |
| 83 | WXK_NUMPAD_SPACE : "WXK_NUMPAD_SPACE", |
| 84 | WXK_NUMPAD_TAB : "WXK_NUMPAD_TAB", |
| 85 | WXK_NUMPAD_ENTER : "WXK_NUMPAD_ENTER", |
| 86 | WXK_NUMPAD_F1 : "WXK_NUMPAD_F1", |
| 87 | WXK_NUMPAD_F2 : "WXK_NUMPAD_F2", |
| 88 | WXK_NUMPAD_F3 : "WXK_NUMPAD_F3", |
| 89 | WXK_NUMPAD_F4 : "WXK_NUMPAD_F4", |
| 90 | WXK_NUMPAD_HOME : "WXK_NUMPAD_HOME", |
| 91 | WXK_NUMPAD_LEFT : "WXK_NUMPAD_LEFT", |
| 92 | WXK_NUMPAD_UP : "WXK_NUMPAD_UP", |
| 93 | WXK_NUMPAD_RIGHT : "WXK_NUMPAD_RIGHT", |
| 94 | WXK_NUMPAD_DOWN : "WXK_NUMPAD_DOWN", |
| 95 | WXK_NUMPAD_PRIOR : "WXK_NUMPAD_PRIOR", |
| 96 | WXK_NUMPAD_PAGEUP : "WXK_NUMPAD_PAGEUP", |
| 97 | WXK_NUMPAD_NEXT : "WXK_NUMPAD_NEXT", |
| 98 | WXK_NUMPAD_PAGEDOWN : "WXK_NUMPAD_PAGEDOWN", |
| 99 | WXK_NUMPAD_END : "WXK_NUMPAD_END", |
| 100 | WXK_NUMPAD_BEGIN : "WXK_NUMPAD_BEGIN", |
| 101 | WXK_NUMPAD_INSERT : "WXK_NUMPAD_INSERT", |
| 102 | WXK_NUMPAD_DELETE : "WXK_NUMPAD_DELETE", |
| 103 | WXK_NUMPAD_EQUAL : "WXK_NUMPAD_EQUAL", |
| 104 | WXK_NUMPAD_MULTIPLY : "WXK_NUMPAD_MULTIPLY", |
| 105 | WXK_NUMPAD_ADD : "WXK_NUMPAD_ADD", |
| 106 | WXK_NUMPAD_SEPARATOR : "WXK_NUMPAD_SEPARATOR", |
| 107 | WXK_NUMPAD_SUBTRACT : "WXK_NUMPAD_SUBTRACT", |
| 108 | WXK_NUMPAD_DECIMAL : "WXK_NUMPAD_DECIMAL", |
| 109 | WXK_NUMPAD_DIVIDE : "WXK_NUMPAD_DIVIDE", |
| 110 | } |
| 111 | |
| 112 | |
| 113 | #---------------------------------------------------------------------- |
| 114 | |
| 115 | class KeySink(wxWindow): |
| 116 | def __init__(self, parent): |
| 117 | wxWindow.__init__(self, parent, -1, style = |
| 118 | wxWANTS_CHARS |
| 119 | #| wxRAISED_BORDER |
| 120 | #| wxSUNKEN_BORDER |
| 121 | ) |
| 122 | self.SetBackgroundColour(wxBLUE) |
| 123 | self.haveFocus = False |
| 124 | self.callSkip = False |
| 125 | self.logKeyDn = True |
| 126 | self.logKeyUp = True |
| 127 | self.logChar = True |
| 128 | |
| 129 | EVT_PAINT(self, self.OnPaint) |
| 130 | EVT_SET_FOCUS(self, self.OnSetFocus) |
| 131 | EVT_KILL_FOCUS(self, self.OnKillFocus) |
| 132 | EVT_MOUSE_EVENTS(self, self.OnMouse) |
| 133 | |
| 134 | EVT_KEY_DOWN(self, self.OnKeyDown) |
| 135 | EVT_KEY_UP(self, self.OnKeyUp) |
| 136 | EVT_CHAR(self, self.OnChar) |
| 137 | |
| 138 | |
| 139 | def SetCallSkip(self, skip): |
| 140 | self.callSkip = skip |
| 141 | |
| 142 | def SetLogKeyUp(self, val): |
| 143 | self.logKeyUp = val |
| 144 | |
| 145 | def SetLogKeyDn(self, val): |
| 146 | self.logKeyDn = val |
| 147 | |
| 148 | def SetLogChar(self, val): |
| 149 | self.logChar = val |
| 150 | |
| 151 | |
| 152 | def OnPaint(self, evt): |
| 153 | dc = wxPaintDC(self) |
| 154 | rect = self.GetClientRect() |
| 155 | dc.SetTextForeground(wxWHITE) |
| 156 | dc.DrawLabel("Click here and then press some keys", |
| 157 | rect, wxALIGN_CENTER | wxALIGN_TOP) |
| 158 | if self.haveFocus: |
| 159 | dc.SetTextForeground(wxGREEN) |
| 160 | dc.DrawLabel("Have Focus", rect, wxALIGN_RIGHT | wxALIGN_BOTTOM) |
| 161 | else: |
| 162 | dc.SetTextForeground(wxRED) |
| 163 | dc.DrawLabel("Need Focus!", rect, wxALIGN_RIGHT | wxALIGN_BOTTOM) |
| 164 | |
| 165 | |
| 166 | def OnSetFocus(self, evt): |
| 167 | self.haveFocus = True |
| 168 | self.Refresh() |
| 169 | |
| 170 | def OnKillFocus(self, evt): |
| 171 | self.haveFocus = False |
| 172 | self.Refresh() |
| 173 | |
| 174 | def OnMouse(self, evt): |
| 175 | if evt.ButtonDown(): |
| 176 | self.SetFocus() |
| 177 | |
| 178 | |
| 179 | def OnKeyDown(self, evt): |
| 180 | if self.logKeyDn: |
| 181 | self.GetParent().keylog.LogKeyEvent("KeyDown", evt) |
| 182 | if self.callSkip: |
| 183 | evt.Skip() |
| 184 | |
| 185 | def OnKeyUp(self, evt): |
| 186 | if self.logKeyUp: |
| 187 | self.GetParent().keylog.LogKeyEvent("KeyUp", evt) |
| 188 | if self.callSkip: |
| 189 | evt.Skip() |
| 190 | |
| 191 | def OnChar(self, evt): |
| 192 | if self.logChar: |
| 193 | self.GetParent().keylog.LogKeyEvent("Char", evt) |
| 194 | |
| 195 | |
| 196 | #---------------------------------------------------------------------- |
| 197 | |
| 198 | from wxPython.lib.mixins.listctrl import wxListCtrlAutoWidthMixin |
| 199 | |
| 200 | class KeyLog(wxListCtrl, wxListCtrlAutoWidthMixin): |
| 201 | |
| 202 | def __init__(self, parent): |
| 203 | wxListCtrl.__init__(self, parent, -1, |
| 204 | style = wxLC_REPORT|wxLC_VRULES|wxLC_HRULES) |
| 205 | wxListCtrlAutoWidthMixin.__init__(self) |
| 206 | |
| 207 | self.InsertColumn(0, "Event Type") |
| 208 | self.InsertColumn(1, "Key Name") |
| 209 | self.InsertColumn(2, "Key Code") |
| 210 | self.InsertColumn(3, "Modifiers") |
| 211 | self.InsertColumn(4, "RawKeyCode") |
| 212 | self.InsertColumn(5, "RawKeyFlags") |
| 213 | self.InsertColumn(6, "") |
| 214 | |
| 215 | for x in range(6): |
| 216 | self.SetColumnWidth(x, wxLIST_AUTOSIZE_USEHEADER) |
| 217 | |
| 218 | self.SetColumnWidth(1, 125) |
| 219 | |
| 220 | |
| 221 | def LogKeyEvent(self, evType, evt): |
| 222 | keycode = evt.GetKeyCode() |
| 223 | keyname = keyMap.get(keycode, None) |
| 224 | if keyname is None: |
| 225 | if keycode < 256: |
| 226 | if keycode == 0: |
| 227 | keyname = "NUL" |
| 228 | elif keycode < 27: |
| 229 | keyname = "Ctrl-%s" % chr(ord('A') + keycode-1) |
| 230 | else: |
| 231 | keyname = "\"%s\"" % chr(keycode) |
| 232 | else: |
| 233 | keyname = "unknown (%s)" % keycode |
| 234 | |
| 235 | modifiers = "" |
| 236 | for mod, ch in [(evt.ControlDown(), 'C'), |
| 237 | (evt.AltDown(), 'A'), |
| 238 | (evt.ShiftDown(), 'S'), |
| 239 | (evt.MetaDown(), 'M')]: |
| 240 | if mod: |
| 241 | modifiers += ch |
| 242 | else: |
| 243 | modifiers += '-' |
| 244 | |
| 245 | id = self.InsertStringItem(self.GetItemCount(), evType) |
| 246 | self.SetStringItem(id, 1, keyname) |
| 247 | self.SetStringItem(id, 2, str(keycode)) |
| 248 | self.SetStringItem(id, 3, modifiers) |
| 249 | self.SetStringItem(id, 4, str(evt.GetRawKeyCode())) |
| 250 | self.SetStringItem(id, 5, str(evt.GetRawKeyFlags())) |
| 251 | |
| 252 | #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags())) |
| 253 | |
| 254 | self.EnsureVisible(id) |
| 255 | |
| 256 | |
| 257 | def ClearLog(self): |
| 258 | self.DeleteAllItems() |
| 259 | |
| 260 | |
| 261 | #---------------------------------------------------------------------- |
| 262 | |
| 263 | |
| 264 | class TestPanel(wxPanel): |
| 265 | def __init__(self, parent, log): |
| 266 | self.log = log |
| 267 | wxPanel.__init__(self, parent, -1, style=0) |
| 268 | self.keysink = KeySink(self) |
| 269 | self.keysink.SetSize((100, 65)) |
| 270 | self.keylog = KeyLog(self) |
| 271 | |
| 272 | btn = wxButton(self, -1, "Clear Log") |
| 273 | EVT_BUTTON(self, btn.GetId(), self.OnClearBtn) |
| 274 | |
| 275 | cb1 = wxCheckBox(self, -1, "Call evt.Skip for Key Up/Dn events") |
| 276 | EVT_CHECKBOX(self, cb1.GetId(), self.OnSkipCB) |
| 277 | |
| 278 | cb2 = wxCheckBox(self, -1, "EVT_KEY_UP") |
| 279 | EVT_CHECKBOX(self, cb2.GetId(), self.OnKeyUpCB) |
| 280 | cb2.SetValue(True) |
| 281 | |
| 282 | cb3 = wxCheckBox(self, -1, "EVT_KEY_DOWN") |
| 283 | EVT_CHECKBOX(self, cb3.GetId(), self.OnKeyDnCB) |
| 284 | cb3.SetValue(True) |
| 285 | |
| 286 | cb4 = wxCheckBox(self, -1, "EVT_CHAR") |
| 287 | EVT_CHECKBOX(self, cb4.GetId(), self.OnCharCB) |
| 288 | cb4.SetValue(True) |
| 289 | |
| 290 | buttons = wxBoxSizer(wxHORIZONTAL) |
| 291 | buttons.Add(btn, 0, wxALL, 4) |
| 292 | buttons.Add(cb1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 6) |
| 293 | buttons.Add(cb2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 6) |
| 294 | buttons.Add(cb3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 6) |
| 295 | buttons.Add(cb4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 6) |
| 296 | |
| 297 | sizer = wxBoxSizer(wxVERTICAL) |
| 298 | sizer.Add(self.keysink, 0, wxGROW) |
| 299 | sizer.Add(buttons) |
| 300 | sizer.Add(self.keylog, 1, wxGROW) |
| 301 | |
| 302 | self.SetSizer(sizer) |
| 303 | |
| 304 | |
| 305 | def OnClearBtn(self, evt): |
| 306 | self.keylog.ClearLog() |
| 307 | |
| 308 | def OnSkipCB(self, evt): |
| 309 | self.keysink.SetCallSkip(evt.GetInt()) |
| 310 | |
| 311 | def OnKeyUpCB(self, evt): |
| 312 | self.keysink.SetLogKeyUp(evt.GetInt()) |
| 313 | |
| 314 | def OnKeyDnCB(self, evt): |
| 315 | self.keysink.SetLogKeyDn(evt.GetInt()) |
| 316 | |
| 317 | def OnCharCB(self, evt): |
| 318 | self.keysink.SetLogChar(evt.GetInt()) |
| 319 | |
| 320 | |
| 321 | #---------------------------------------------------------------------- |
| 322 | |
| 323 | def runTest(frame, nb, log): |
| 324 | win = TestPanel(nb, log) |
| 325 | return win |
| 326 | |
| 327 | #---------------------------------------------------------------------- |
| 328 | |
| 329 | |
| 330 | |
| 331 | overview = """<html><body> |
| 332 | <h2><center>wxKeyEvents</center></h2> |
| 333 | |
| 334 | This demo simply lets catches all key events and prints info about them. |
| 335 | It is meant to be used as a compatibility test for cross platform work. |
| 336 | |
| 337 | </body></html> |
| 338 | """ |
| 339 | |
| 340 | |
| 341 | |
| 342 | if __name__ == '__main__': |
| 343 | import sys,os |
| 344 | import run |
| 345 | run.main(['', os.path.basename(sys.argv[0])]) |
| 346 | |