我正在开发 Tkinter Python 程序,我需要在希腊语和其他语言之间切换进行输入。我的问题是,我必须使用重写每个键绑定并检查键代码以执行正确的功能。
widget.bind(<Control-z>, undo)
它不适用于希腊语等键盘布局。但是,如果可以指定键码而不是键符号,那就更容易了。
widget.bind(<Control-Keycode-52>, undo)
我已经制作了自己的 Entry 小部件来处理此问题,但它涉及必须编写新的复制、粘贴、选择、移动到末尾等功能。然后我必须对顶级窗口等做同样的事情...这是很多工作。
某些库中已经有这样的解决方案,或者有人有一种优雅的方法来处理这个问题吗?
我认为没有直接的方法可以
bind
到Keycode
。您必须使用解决方法来完成您想要的操作。
一种方法是对
<KeyPress>
进行一般绑定,并添加一些 if-else
语句来检查特定的 Keycode
。
但是我考虑了通用化代码,这样就可以生成小部件可以
bind
的特殊事件,而不是仅仅使用检查。代码示例:
import tkinter as tk
root = tk.Tk()
def generate_keycode_event(event: tk.Event):
pressed_on: tk.Widget = event.widget
special = ''
if isinstance(event.state, int): # probably not needed
state = event.state
mods = {'Shift': 0, 'Control': 2, 'Alt': 17}
for key in mods:
if state & (1 << mods[key]):
special += key + '-'
pressed_on.event_generate(f"<<{special}Keycode-{event.keycode}>>", x=event.x, y=event.y, sendevent=event.send_event)
root.bind('<KeyPress>', generate_keycode_event)
ent = tk.Entry()
ent.pack()
ent.bind('<<Control-Keycode-90>>', lambda e: print('Undo!')) # Keycode-90 is "z"
root.mainloop()
此代码应该允许您做您想做的事情,而无需使用
if
测试。但这可能不是理想的代码。可能会出现一些问题。
代码上的一些注释:
由于我使用的是
root
绑定,如果您需要将其他一些键绑定到 root
,则必须在额外绑定的末尾添加 add='+'
参数。
如果需要,您可以添加几个额外的模组。例如,如果要定义使用的“Lock”键,可以在“mods”中添加“Lock”: 1。只需尝试使用
event.state
即可获得其他模组。我发现了一些:
extra_mods = {'Shift': 0, 'Lock': 1, 'Control': 2, 'Mod1': 3, 'Mod2': 4, 'Mod3': 5,
'Mod4': 6, 'Mod5': 7, 'Button1': 8, 'Button2': 9, 'Button3': 10,
'Button4': 11, 'Button5': 12, 'Alt': 17, 'NumLock': 18}