首页 > 解决方案 > Tkinter 在绑定到时双重打印字符

问题描述

我有一系列 16 个 Tk Entry 小部件,我想将它们绑定到 <Key> 事件,以便填充具有可见效果的任何内容(如 a、7 和 *),而任何没有立即可见效果的键都有其键符表示代替(Return、Tabx、Shift_L 等...)

如果我将 <Key> 绑定到这些 Entry 小部件中的每一个,则任何带有可见 event.char 的东西都会打印出来。任何有隐形的东西都没有。如果我将 <Key> 绑定到根,则不会发生这种情况。

考虑到我的实际程序有几个按钮和一个画布,将 <Key> 绑定到 root 是不是一个坏主意?
如果是这样,我怎样才能将它单独绑定到每个小部件并避免在没有空 event.char 的情况下重复打印任何内容?

#!/usr/bin/env python
#sample.py
import tkinter as tk

def set_key(event):
    print(f"Key: '{event.char}', '{event.keysym}'")
    focus = root.focus_get()
    focus.delete(0, tk.END)
    if (event.char.split() != []):
        focus.insert(0, event.char)
    else:
        focus.insert(0, event.keysym)

root = tk.Tk()
root.option_add("*Font", "24")

keys = ["1", "2", "3", "4", "q", "w", "e", "r", "a", "s", "d", "f", "z", "x", "c", "v"]
keyboard_entries = []
for idx in range(16):
    keyboard_entries.append(tk.Entry(root, width=7))
    keyboard_entries[idx].grid(row=(idx//4), column=(idx%4))
    keyboard_entries[idx].insert(0, keys[idx])
    #keyboard_entries[idx].bind("<Key>", set_key) #Problematic

root.bind("<Key>", set_key) #Not problematic
root.mainloop()

绑定到根
时的结果 绑定到每个条目时的结果

标签: pythontkintertkinter-entry

解决方案


考虑到我的实际程序有几个按钮和一个画布,绑定到 root 是不是一个坏主意?

是的,这是个坏主意。绑定到 root 意味着每个小部件都会受到影响。

如果是这样,我如何将它单独绑定到每个小部件并避免在没有空 event.char 的情况下重复打印任何内容

好吧,您总是可以单独绑定到每个小部件。看起来你已经尝试过了,但不清楚你为什么认为它不起作用。

keyboard_entries[idx].bind("<Key>", set_key)

至于如何不获取双字符,问题在于默认绑定键是在调用绑定函数之后发生的。最简单的解决方案是通过从函数中返回“break”来防止原始绑定触发。

此外,您不需要在函数中获得焦点,因为event对象的一部分是对接收事件的小部件的引用。

def set_key(event):
    event.widget.delete(0, "end")
    if (event.char.split() != []):
        event.widget.insert(0, event.char)
    else:
        event.widget.insert(0, event.keysym)
    return "break"

有关事件和绑定的详细说明,请参阅此答案:http ://stackoverflow.com/a/11542200/7432


推荐阅读