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
答案 0 :(得分:16)
使用Tkinter,“Control-R”表示 Ctrl - Shift - R 而“Control-r”表示 Ctrl < / KBD> - - [R 。因此,请确保您没有混合使用大写和小写。
答案 1 :(得分:5)
这似乎是Tk中的一个错误。我在mac以及python / tkinter上使用tcl / tk得到了同样的错误。您可以将<Command-e>
绑定到窗口小部件(我尝试使用文本窗口小部件),但将其绑定到根窗口或"all"
似乎会导致出现错误。
答案 2 :(得分:0)
这样的事情:
# 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()
答案 3 :(得分:0)
增强了在MacOS上涵盖Alt
和Meta
键(又名Option
和Command
)的功能。
# Original <https://StackOverflow.com/questions/6378556/
# multiple-key-event-bindings-in-tkinter-control-e-command-apple-e-etc>
# Status of alt (ak option), control, meta (aka command)
# and shift keys in Python tkinter
# Note, tested only on macOS 10.13.6 with Python 3.7.4 and Tk 8.6.9
import tkinter as tk
import sys
_macOS = sys.platform == 'darwin'
_Alt = 'Option' if _macOS else 'Alt'
_Ctrl = 'Control'
_Meta = 'Command' if _macOS else 'Meta'
_Shift = 'Shift'
alt = ctrl = meta = shift = ''
def up_down(mod, down):
print('<%s> %s' % (mod, 'down' if down else 'up'))
return down
def key(event):
'''Other key pressed or released'''
# print(event.keycode, event.keysym, event.down)
global alt, ctrl, meta, shift
t = [m for m in (alt, ctrl, shift, meta, str(event.keysym)) if m]
print('+'.join(t))
def alt_key(down, *unused):
'''Alt (aka Option on macOS) key is pressed or released'''
global alt
alt = up_down(_Alt, down)
def control_key(down, *unused):
'''Control key is pressed or released'''
global ctrl
ctrl = up_down(_Ctrl, down)
def meta_key(down, *unused):
'''Meta (aka Command on macOS) key is pressed or released'''
global meta
meta = up_down(_Meta, down)
def shift_key(down, *unused):
'''Shift button is pressed or released'''
global shift
shift = up_down(_Shift, down)
def modifier(root, mod, handler, down):
'''Add events and handlers for key press and release'''
root.event_add('<<%sOn>>' % (mod,), ' <KeyPress-%s_L>' % (mod,), '<KeyPress-%s_R>' % (mod,))
root.bind( '<<%sOn>>' % (mod,), lambda _: handler('<%s>' % (down,)))
root.event_add('<<%sOff>>' % (mod,), '<KeyRelease-%s_L>' % (mod,), '<KeyRelease-%s_R>' % (mod,))
root.bind( '<<%sOff>>' % (mod,), lambda _: handler(''))
root = tk.Tk()
root.geometry('256x64+0+0')
modifier(root, 'Alt', alt_key, _Alt)
modifier(root, 'Control', control_key, _Ctrl)
modifier(root, 'Meta', meta_key, _Meta)
modifier(root, 'Shift', shift_key, _Shift)
root.bind('<Key>', key)
root.mainloop()