2011-06-16 64 views
7

的Mac OS X 10.6.6 - Tkinter的多鍵事件綁定在Tkinter的 - 「控制+ E」的「命令(蘋果)+ E」等

我想綁定多個按鍵事件,而我已經找到一個effbot文章和Tk手冊頁,我一直無法使這個工作正確。我是新來的。

我有混合的成功。我已經能夠獲得Shift +字母鍵,但不能控制或命令(Apple鍵)。我真正想要做的是Command +字母和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 /選項+(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 

回答

5

這似乎是Tk中的一個錯誤。我在mac上以及python/tkinter上遇到了與tcl/tk相同的錯誤。您可以將<Command-e>綁定到小部件(我嘗試使用文本小部件),但將其綁定到根窗口或"all"似乎會導致出現錯誤。

+0

謝謝,我沒有經驗,知道它是否是一個錯誤或我的錯誤...通常我的。 – Ray 2011-06-17 17:08:24

15

隨着Tkinter的, 「控制-R」 指Ctrl鍵 - - - [R而 「控制-R」 的意思Ctrl鍵 - - [R。所以請確保你不混合大寫和小寫。

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()