wxPython Bind key events

In this post, I’ll detail how to catch specific key presses and why this can be useful. This is another in my series of “requested” tutorials. There really isn’t much to catching key presses, but it can be a little confusing when one widget behaves slightly differently from another. The really complicated stuff comes in when you need to capture the EVT_CHAR.

First I’ll cover the key events, wx.EVT_KEY_DOWN and wx.EVT_KEY_UP and then I’ll go over the intricacies of wx.EVT_CHAR. It is my belief that programming is easiest to understand if you see some sample code, so I’ll start off with simple example:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Key Press Tutorial")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        btn = wx.Button(panel, label="OK")
 
        btn.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
 
    def onKeyPress(self, event):
        keycode = event.GetKeyCode()
        print keycode
        if keycode == wx.WXK_SPACE:
            print "you pressed the spacebar!"
        event.Skip()
 
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm()
    frame.Show()
    app.MainLoop()

You will notice that the only widgets of consequence in this piece of code are a panel and a button. I bind the button to the EVT_KEY_DOWN and in the handler I check if the user has pressed the spacebar. The event only fires if the button has focus. You’ll notice that I also call “event.Skip” at the end. Iif you don’t call Skip, then the key will “eaten” and there won’t be a corresponding char event. This won’t matter on a button, but you might care in a text control as char events are the proper way of catching upper and lower case, accents, umlauts and the like.

I’ve used a similar method to catch arrow key presses in a spreadsheet-type application of mine. I wanted to be able to detect these keys so that if I was editing a cell, an arrow key press would make the selection change to a different cell. That is not the default behavior. In a grid, each cell has its own editor and pressing the arrow keys just moves the cursor around within the cell.

Just for fun, I created a similar example to the one above where I bound to the key and the key down events, but with two different widgets. Check it out below:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Key Press Tutorial 2")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)
 
        btn = self.onWidgetSetup(wx.Button(panel, label="OK"),
                                 wx.EVT_KEY_UP,
                                 self.onButtonKeyEvent, sizer)
        txt = self.onWidgetSetup(wx.TextCtrl(panel, value=""),
                                 wx.EVT_KEY_DOWN, self.onTextKeyEvent,
                                 sizer)
        panel.SetSizer(sizer)
 
    def onWidgetSetup(self, widget, event, handler, sizer):
        widget.Bind(event, handler)
        sizer.Add(widget, 0, wx.ALL, 5)
        return widget
 
    def onButtonKeyEvent(self, event):
        keycode = event.GetKeyCode()
        print keycode
        if keycode == wx.WXK_SPACE:
            print "you pressed the spacebar!"
        event.Skip()
 
    def onTextKeyEvent(self, event):
        keycode = event.GetKeyCode()
        print keycode
        if keycode == wx.WXK_DELETE:
            print "you pressed the delete key!"
        event.Skip()
 
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm()
    frame.Show()
    app.MainLoop()

Admittedly, this is mostly for illustration. The main thing to know is that you really don’t use EVT_KEY_UP unless you need to keep track of multi-key combinations, like CTRL+K+Y or something (on a semi-related note, see the wx.AcceleratorTable). While I’m not doing this in my example, it is important to note that if you are checking for the CTRL key, then it’s best to use event.CmdDown() rather than event.ControlDown. The reason being that CmdDown is the equivalent of ControlDown on Windows and Linux, but on Mac it simulates the Command key. Thus, CmdDown is the best cross-platform way of checking if the CTRL key has been pressed.

And that’s really all you need to know about key events. Let’s go on and see what we can learn about char events. Here’s a simple example:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Char Event Tutorial")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        btn = wx.TextCtrl(panel, value="")
 
        btn.Bind(wx.EVT_CHAR, self.onCharEvent)
 
    def onCharEvent(self, event):
        keycode = event.GetKeyCode()
        controlDown = event.CmdDown()
        altDown = event.AltDown()
        shiftDown = event.ShiftDown()
 
        print keycode
        if keycode == wx.WXK_SPACE:
            print "you pressed the spacebar!"
        elif controlDown and altDown:
            print keycode
        event.Skip()
 
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm()
    frame.Show()
    app.MainLoop()

I think the main thing that is different is that you want to check for accents or international characters. Thus, you’ll have complex conditionals that check if certain keys are pressed and in what order. Robin Dunn (creator of wxPython) said that wxSTC checks for both key and char events. If you plan on supporting users outside the USA, you’ll probably want to learn how this all works.

Robin Dunn went on to say that if you want to get the key events in order to handle “commands” within the application, then using the raw values in a EVT_KEY_DOWN handler is appropriate. However if the intent is to handle the entry of “text” then the app should use the cooked values in an EVT_CHAR event handler in order to get the proper handling for non US keyboards and input method editors. (Note: key up and key down events are considered “raw” whereas char events have been “cooked” for you.) As Robin Dunn explained it to me, on non-US keyboards then part of cooking the key events into char events is mapping the physical keys to the national keyboard map, to produce characters with accents, umlauts, and such.

I apologize that this tutorial doesn’t cover more on char events, but I just couldn’t find much for examples.

These code samples were tested on the following

  • Windows Vista SP2, wxPython 2.8.9.2 (unicode), Python 2.5.2

-->

wxPython Bind key events

时间: 2024-10-06 08:06:17

wxPython Bind key events的相关文章

e636. Listening to All Key Events Before Delivery to Focused Component

Registering a key event dispatcher with the keyboard focus manager allows you to see all key events before they are sent to the focused component. It is possible to modify the event or even prevent the event from being delivered. KeyboardFocusManager

【技术分享】很详细的JS底层分析

1. 序言现在学的东西很容易忘记,写这篇文章的目的是能让我在需要时快速找回当时的感觉. 入门学习和参考手册建议翻阅JavaScript.The.Definitive.Guide.5th.Edition的附录(有电子版). 2. 准备设置服务器*.xml的MIME为text/xml ,Windows Xp自带的IIS的设置如下图 js_0000.png Firefox上有许多插件是开发必备的,用法大家Google,我列一下名称 FireBug Web Developer Toolbar Greas

wxPython 键盘事件列表

wx.KeyEvent    Home       Trees       Index       Help    wxPython 2.8.9.2 Package wx :: Class KeyEvent [frames | no frames] Type KeyEvent object --+ | Object --+ | Event --+ | KeyEvent This event class contains information about keypress and charact

ZigBee Device Object End Device Bind Request--协调器与终端之间的绑定

这里主要讲述协调器和终端之间的绑定. This mechanism uses a button press or other similar action at the selected devices to bind within a specific timeout period.  The End Device Bind Request messages are collected at the coordinator within the timeout period and a res

【Xamarin笔记】Events, Protocols and Delegates

Events, Protocols and Delegates   事件.协议和委托 This article presents the key iOS technologies used to receive callbacks and to populate user interface controls with data. These technologies are events, protocols, and delegates. This article explains what

Python3 Tkinter基础 Frame bind 绑定敲击键盘事件 将按键打印到Shell中

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: from tkinter import * root=Tk() #创建一个框架,在这个框架中响应事件 frame=Frame(root, width=200,height=200, background='green') def callBack(event):

Document Object Model (DOM) Level 3 Events Specification

Document Object Model (DOM) Level 3 Events Specification W3C Working Draft 25 September 2014 This version: http://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/ Latest published version: http://www.w3.org/TR/DOM-Level-3-Events/ Latest editor's dr

wxpython wx.windows的API

wx.Window is the base class for all windows and represents any visible object on screen. All controls, top level windows and so on are windows. Sizers and device contexts are not, however, as they don't appear on screen themselves. Please note that a

jQuery源码

/*! * jQuery JavaScript Library v1.8.3 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: Tue Nov 13 20