Tkinter中的多个键事件绑定 - “Control + E”“Command(apple)+ E”等

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tkinter中的多个键事件绑定 - “Control + E”“Command(apple)+ E”等相关的知识,希望对你有一定的参考价值。

Mac OS X 10.6.6 - Tkinter

我想绑定多键事件,虽然我找到了一篇文章和Tk手册页,但我一直无法正常工作。我是新来的。

我的成功喜忧参半。我已经能够获得Shift +字母键,但不能获得Control或Command(Apple键)。我真正想做的是Command + letter和Control +字母键,因此它理论上可以在Windows和OS X中使用。

我希望它在窗口级工作,所以我使用root。也许有更好的方法。以下是我尝试过的内容:

root.bind('<Shift-E>', self.pressedCmdE)   # Works
root.bind('e', self.pressedCmdE)           # Works
root.bind('<Command-E>', self.pressedCmdE) # Does Not Work
#root.bind('<Mod1-E>', self.pressedCmdE)   #   # Do Mod1, M1, and
#root.bind('<M1-E>', self.pressedCmdE)     #   # Command mean the same thing?

奇怪的是,当我按alt / option +(E,N或其他)时,会产生错误。它是否与PythonLauncher交互?

2011-06-16 16:19:22.618 Python[1546:d07] An uncaught exception was raised
2011-06-16 16:19:22.621 Python[1546:d07] *** -[NSCFString characterAtIndex:]: Range or index out of bounds
2011-06-16 16:19:22.622 Python[1546:d07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFString characterAtIndex:]: Range or index out of bounds'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff85b397b4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff848b90f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b395d7 +[NSException raise:format:arguments:] + 103
    3   CoreFoundation                      0x00007fff85b39564 +[NSException raise:format:] + 148
    4   Foundation                          0x00007fff866eb5e1 -[NSCFString characterAtIndex:] + 97
    5   Tk                                  0x0000000100759bcf Tk_SetCaretPos + 663
    6   Tk                                  0x000000010075fd94 Tk_MacOSXSetupTkNotifier + 699
    7   Tcl                                 0x000000010061d2ae Tcl_DoOneEvent + 297
    8   _tkinter.so                         0x00000001001d9be9 init_tkinter + 1132
    9   Python                              0x0000000100089187 PyEval_EvalFrameEx + 15317
    10  Python                              0x000000010008acce PyEval_EvalCodeEx + 1803
    11  Python                              0x000000010008935e PyEval_EvalFrameEx + 15788
    12  Python                              0x000000010008acce PyEval_EvalCodeEx + 1803
    13  Python                              0x000000010008ad61 PyEval_EvalCode + 54
    14  Python                              0x00000001000a265a Py_CompileString + 78
    15  Python                              0x00000001000a2723 PyRun_FileExFlags + 150
    16  Python                              0x00000001000a423d PyRun_SimpleFileExFlags + 704
    17  Python                              0x00000001000b0286 Py_Main + 2718
    18  Python                              0x0000000100000e6c start + 52
)
terminate called after throwing an instance of 'NSException'
Abort trap
答案

这似乎是Tk中的一个错误。我在mac以及python / tkinter上使用tcl / tk得到了同样的错误。你可以将<Command-e>绑定到一个小部件(我尝试使用文本小部件)但是将它绑定到根窗口或"all"似乎会导致你得到的错误。

另一答案

对于Tkinter,“Control-R”表示Ctrl-Shift-R,而“Control-r”表示Ctrl-R。因此,请确保您没有混合使用大写和小写。

另一答案

像这样的东西:

# Status of control, shift and control+shift keys in Python
import tkinter as tk

ctrl = False
shift = False
ctrl_shift = False

def key(event):
    global ctrl, shift, ctrl_shift
    #print(event.keycode, event.keysym, event.state)
    if ctrl_shift:
        print('<Ctrl>+<Shift>+{}'.format(event.keysym))
    elif ctrl:
        print('<Ctrl>+{}'.format(event.keysym))
    elif shift:
        print('<Shift>+{}'.format(event.keysym))
    ctrl = False
    shift = False
    ctrl_shift = False

def control_key(state, event=None):
    ''' Controll button is pressed or released '''
    global ctrl
    ctrl = state

def shift_key(state, event=None):
    ''' Controll button is pressed or released '''
    global shift
    shift = state
    control_shift(state)

def control_shift(state):
    ''' <Ctrl>+<Shift> buttons are pressed or released '''
    global ctrl, ctrl_shift
    if ctrl == True and state == True:
        ctrl_shift = True
    else:
        ctrl_shift = False

root = tk.Tk()
root.geometry('256x256+0+0')

root.event_add('<<ControlOn>>',  '<KeyPress-Control_L>',   '<KeyPress-Control_R>')
root.event_add('<<ControlOff>>', '<KeyRelease-Control_L>', '<KeyRelease-Control_R>')
root.event_add('<<ShiftOn>>',    '<KeyPress-Shift_L>',     '<KeyPress-Shift_R>')
root.event_add('<<ShiftOff>>',   '<KeyRelease-Shift_L>',   '<KeyRelease-Shift_R>')

root.bind('<<ControlOn>>', lambda e: control_key(True))
root.bind('<<ControlOff>>', lambda e: control_key(False))
root.bind('<<ShiftOn>>', lambda e: shift_key(True))
root.bind('<<ShiftOff>>', lambda e: shift_key(False))
root.bind('<Key>', key)

root.mainloop()

以上是关于Tkinter中的多个键事件绑定 - “Control + E”“Command(apple)+ E”等的主要内容,如果未能解决你的问题,请参考以下文章

tkinter 事件与绑定

3.8 tkinter 事件绑定的参数传递

如何将点击事件绑定到 Tkinter 中的画布? [关闭]

如何将空格键键绑定到tkinter(python)中的某个方法

[Tkinter 教程15] event 事件绑定

python tkinter treeview右键单击(Button-3)事件以选择树视图中的项目