Events Tkinter-中的多个键事件绑定;控制+;"&引用;指挥部(苹果)和#x2B;";等

Events Tkinter-中的多个键事件绑定;控制+;"&引用;指挥部(苹果)和#x2B;";等,events,binding,command,key,tkinter,Events,Binding,Command,Key,Tkinter,Mac OS X 10.6.6-Tkinter 我想绑定多个关键事件,虽然我已经找到了一篇effbot文章和Tk手册页,但我无法正确地实现这一点。我是新来的 我的成功好坏参半。我已经能够得到Shift+字母键,但不能控制或命令(苹果键)。我真正想做的是Command+letter和Control+letter键,这样理论上它可以在Windows和OSX中工作 我希望它在窗口级别工作,所以我使用root。也许有更好的办法。以下是我尝试过的: root.bind('<Shift-E>',

Mac OS X 10.6.6-Tkinter

我想绑定多个关键事件,虽然我已经找到了一篇effbot文章和Tk手册页,但我无法正确地实现这一点。我是新来的

我的成功好坏参半。我已经能够得到Shift+字母键,但不能控制或命令(苹果键)。我真正想做的是Command+letter和Control+letter键,这样理论上它可以在Windows和OSX中工作

我希望它在窗口级别工作,所以我使用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?

这似乎是Tk中的一个bug。我在mac上的tcl/tk以及python/tkinter上都遇到了同样的错误。您可以将
绑定到小部件(我尝试使用文本小部件),但将其绑定到根窗口或
“all”
似乎会导致出现错误

对于Tkinter,“Control-R”表示Ctrl-Shift-R,而“Control-R”表示Ctrl-R。因此,请确保不要混淆大小写。

选项1

大概是这样的:

# 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()
然后添加了
self.\u击键
功能,以监控
击键事件。此功能检查是否按下了
键:

def __keystroke(self, event):
    """ Language independent handle events from the keyboard """
    #print(event.keycode, event.keysym, event.state)  # uncomment it for debug purposes
    if event.state - self.__previous_state == 4:  # check if <Control> key is pressed
        for shortcut in self.__shortcuts:
            if event.keycode == shortcut[1]:
                shortcut[2]()
    else:  # remember previous state of the event
        self.__previous_state = event.state

增强以覆盖macOS上的
Alt
Meta
键,即
选项和
命令

# 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()
#原件
#alt(ak选项)、控件、元(aka命令)的状态
#Python tkinter中的键和shift键
#注意,仅在macOS 10.13.6上使用Python 3.7.4和Tk 8.6.9进行了测试
将tkinter作为tk导入
导入系统
_macOS=sys.platform==“达尔文”
_Alt='Option'如果_macoselse'Alt'
_Ctrl='Control'
_Meta='Command'如果_macoselse'Meta'
_Shift='Shift'
alt=ctrl=meta=shift=''
def上下(mod,down):
打印(“%s%”(如果向下,则为“向下”,否则为“向上”))
返回
def键(事件):
''按下或释放其他键''
#打印(event.keycode、event.keysym、event.down)
全局alt、ctrl、meta、shift
t=[m表示m in(alt、ctrl、shift、meta、str(event.keysym)),如果m]
打印(“+”.join(t))
def alt_键(向下,*未使用):
''按下或释放Alt(macOS上的又名选项)键''
全局alt
alt=上下(_alt,下)
def控制键(向下,*未使用):
''按下或释放控制键''
全局控制
ctrl=上下(_ctrl,下)
def meta_键(向下,*未使用):
按下或释放“Meta(macOS上的又名命令)键”
全局元
元=上下(\u元,下)
def shift_键(向下,*未使用):
''按下或释放换档按钮''
全球转移
shift=上下(\u shift,down)
def修改器(根、修改器、处理程序、向下):
''为按键和释放添加事件和处理程序''
root.event\u add(“”%(mod,),“”%(mod,),“”%(mod,))
root.bind(“”%(mod,),lambda:handler(“”%(down,))
root.event\u add(“”%(mod,),“”%(mod,),“”%(mod,))
root.bind(“”%(mod,),lambda:处理程序(“”))
root=tk.tk()
根几何体('256x64+0+0')
修饰符(根,'Alt',Alt\u键,\u-Alt)
修饰符(根,“控制”,控制键,\u Ctrl)
修饰符(根,'Meta',Meta_键,_-Meta)
修饰符(根,'Shift',Shift\u键,\u Shift)
root.bind(“”,键)
root.mainloop()

谢谢,我没有经验知道这是错误还是我的错误……通常是我的错误。这是一个非常重要的提示。但在我看来,你只是特别对。一切取决于信的大小写<代码>“
仅在禁用Caps Lock时表示Ctrl-Shift-R,否则等于Ctrl-R。“绑定”仅在禁用Caps Lock时表示Ctrl-R,在启用Caps Lock时表示Ctrl-Shift-R。
def __keystroke(self, event):
    """ Language independent handle events from the keyboard """
    #print(event.keycode, event.keysym, event.state)  # uncomment it for debug purposes
    if event.state - self.__previous_state == 4:  # check if <Control> key is pressed
        for shortcut in self.__shortcuts:
            if event.keycode == shortcut[1]:
                shortcut[2]()
    else:  # remember previous state of the event
        self.__previous_state = event.state
# Handle keystrokes in the idle mode, because program slows down on a weak computers,
# when too many key stroke events in the same time.
self.master.bind('<Key>', lambda event: self.master.after_idle(self.__keystroke, event))
# 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()