【问题标题】:Bind only significant keys on tk/tkinter只绑定 tk/tkinter 上的重要键
【发布时间】:2021-07-15 23:47:03
【问题描述】:

您能否告诉我是否有一种方便的方法可以仅在 tk/tkinter 的“重要”键上进行绑定?

所以,情况是我在 tk.Entry 上有一个绑定(因为我需要在按键被按下时触发回调),如下所示:

myEntry.bind('<Key>', ...)

现在,无论按下什么键都会触发绑定回调(即使是 shift!),但 我希望它仅在“重要”键上触发...通过“重要”我的意思是每个涉及条目中文本更改的键,所以“重要”键肯定是字母、数字、符号和退格键或删除键,但不是箭头键、home、end、pgUp/Down 或选项卡、大写锁定、shift、ctrl 等...(我仍在考虑是否需要它在返回键上触发,但这不是问题,因为如果我也需要它,我可以添加一个特定的绑定它或以其他方式在稍后的回调中忽略它)

我不知道是否有与&lt;Key&gt; 不同的东西我可以绑定以获得我需要的东西,是吗? 否则,如果没有,我知道我可以通过查看事件键码来获取按下了哪个键......这是要走的路吗?如果是的话,你能建议我一些合适的键码间隔吗?

谢谢

【问题讨论】:

  • event.char 会给你钥匙
  • @Matiiss 是的,我认为它的工作方式与 event.keycode 类似,但是它给出的不是数字代码,而是键名(字符串)......然后,如果我必须这样做,事件.keycode 可能更适合过滤我猜...
  • 不是真的,是吗?因为它们不会根据系统而改变吗?
  • 这能回答你的问题吗? Python tkinter text modified callback 键事件绑定不会看到所有可能的变化 - 如果用户仅使用鼠标粘贴文本会怎样?
  • “因为我需要在按键被按下时触发回调” - 出于好奇,按下按键时是否需要绑定,或者是真正的问题每当条目的内容发生变化时,您需要一个回调来运行吗?如果是后者,回调在做什么?它是在验证输入还是其他什么?

标签: python python-3.x tkinter tk


【解决方案1】:

在评论中,您说您正在对列表框进行实时过滤。为此,可以说在变量上设置跟踪比在入口小部件上设置绑定更好。跟踪只会在值发生变化时被调用,因此您不必区分是哪个键触发了变化。

这里有一个简单的例子来说明这个概念:

import tkinter as tk

widgets = [w.__name__ for w in tk.Widget.__subclasses__()]

root = tk.Tk()
entryvar = tk.StringVar()
entry = tk.Entry(root, textvariable=entryvar)
listbox = tk.Listbox(root)
entry.pack(side="top", fill="x")
listbox.pack(side="bottom", fill="both", expand=True)
listbox.insert("end", *sorted(widgets))

after_id = None

def filter_changed(*args):
    global after_id
    if after_id:
        root.after_cancel(after_id)

    # delay actual filtering slightly, in case the user is typing fast.
    after_id = root.after(500, filter_listbox)

def filter_listbox(*args):
    pattern = entryvar.get()
    filtered_widgets = [w for w in widgets if w.startswith(pattern) ]
    listbox.delete(0, "end")
    listbox.insert("end", *filtered_widgets)

entryvar.trace("wu", filter_changed)

root.mainloop()

【讨论】:

  • 再次感谢布莱恩
【解决方案2】:

这是我的解决方案,它使用event.char 并针对带有字符的字符串进行评估(如果需要,可以添加更多字符):

from tkinter import Tk, Entry


string = r"""0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"""


def key_press(event):
    if event.char and event.char in string:
        print(event.char)


root = Tk()

entry = Entry(root)
entry.pack()
entry.bind('<Key>', key_press)

root.mainloop()

【讨论】:

  • 这很有趣,但也需要接受退格键和删除键。除此之外,我不知道当您粘贴内容(或其中的一部分)时会发生什么
  • @danicotra 那么你不想要什么钥匙
  • 两个event.char的目的是什么? if event.char and event.char.
  • @CoolCloud 有时没有字符但也没有错误所以我检查.char 是否存在,如果第一次检查没有到位,它会打印空白
  • @danicotra 粘贴内容实际上只会触发ctrl + v,所以我猜关于退格,什么都不应该打印,你可以使用.keysym.keycode 并进行额外检查,但这些按钮只是少数,所以大多数人会以更简单的方式进行检查
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多