简体   繁体   English

只绑定 tk/tkinter 上的重要键

[英]Bind only significant keys on tk/tkinter

Can you please tell me if there's a convenient way to have a bind only on "significant" keys with tk/tkinter?您能否告诉我是否有一种方便的方法可以仅在 tk/tkinter 的“重要”键上进行绑定?

So, the situation is I have a bind on a tk.Entry (because I need a callback to trigger while keys are being pressed), like this:所以,情况是我在 tk.Entry 上有一个绑定(因为我需要在按键被按下时触发回调),如下所示:

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

Right now, the bind callback is triggered whatever key is pressed (even if it is the shift!) but I'd want it to trigger only on "significant" keys ... By "significant" I mean every key that involve changes on the text in the Entry, so "significant" keys are for sure letters, numbers, symbols and the backspace or delete keys, but NOT arrow keys, home, end, pgUp/Down or also the tab, caps-lock, shift, ctrl, etc... (I'm still thinking if I will need it to trigger on return key or not but that's not a problem, because if I need it too I could add a specific bind on it or otherwise have it ignored in the callback later)现在,无论按下什么键都会触发绑定回调(即使它是 shift!)但我希望它仅在“重要”键上触发......“重要”是指每个涉及更改的键条目中的文本,因此“重要”键肯定是字母、数字、符号和退格键或删除键,但不是箭头键、home、end、pgUp/Down 或 tab、caps-lock、shift、ctrl等...(我仍在考虑是否需要它在返回键上触发,但这不是问题,因为如果我也需要它,我可以在其上添加一个特定的绑定或以其他方式忽略它稍后再打)

I don't know if perhaps is there something different from <Key> I could bind to get what I need, is it?我不知道是否有与<Key>不同的东西我可以绑定以获得我需要的东西,是吗? Otherwise, if not, I know I can get which key was pressed looking at event keycode... is that the way to go?否则,如果没有,我知道我可以通过查看事件键码来获取按下了哪个键......这是通往 go 的方式吗? If yes, can you suggest me some suitable keycode interval please?如果是的话,你能建议我一些合适的键码间隔吗?

Thank you谢谢

In a comment, you say you are doing real-time filtering of a listbox.在评论中,您说您正在对列表框进行实时过滤。 For that, it would arguably be better to set a trace on a variable rather than setting a binding on the entry widget.为此,可以说在变量上设置跟踪比在入口小部件上设置绑定更好。 The trace will only be called when the value changes, so you don't have to distinguish which key triggered the change.仅当值更改时才会调用跟踪,因此您不必区分哪个键触发了更改。

Here's a simple example that illustrates the concept:下面是一个简单的例子来说明这个概念:

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

Here is my solution, it uses event.char and evaluates against a string with characters (can add more characters if needed):这是我的解决方案,它使用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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM