2011-06-16 11 views
7

Mac OS X 10.6.6 - Tkintermúltiple Clave de eventos enlaces en Tkinter - "Control + E" "Comando (manzana) + E", etc

Quiero enlazar eventos de múltiples claves, y aunque he encontrado un artículo de effbot y las páginas man de Tk, no he podido hacer que esto funcione correctamente. Soy nuevo aqui.

He tenido un éxito desigual. Pude obtener la tecla Shift + letra, pero no Control o Comando (tecla Apple). Lo que realmente quiero hacer es Comando + letra y Control + tecla de letra para que teóricamente funcione en Windows y OS X.

Quiero que funcione a nivel de ventana, entonces estoy usando root. Tal vez hay una mejor manera. A continuación se muestra lo que he intentado:

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? 

Extrañamente, al pulsar Alt/Opción + (E, N, u otros) que crea un error. ¿Está interactuando con 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 

Respuesta

5

Esto parece ser un error en Tk. Obtengo el mismo error con tcl/tk en mac y con python/tkinter. Puede vincular <Command-e> a un widget (lo intenté con un widget de texto) pero vincularlo a la ventana raíz o al "all" parece causar el error que obtiene.

+0

Gracias, no tengo la experiencia para saber si se trata de un error o de mi error ... por lo general la mía. – Ray

15

Con Tkinter, "Control-R" significa Ctrl - Shift - R mientras que "Control-r" significa Ctrl - R. Así que asegúrese de no mezclar letras mayúsculas y minúsculas.

0

Algo como esto:

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