Tkinter дважды печатает символы при привязке к ‹Key›

У меня есть серия из 16 виджетов Tk Entry, к которым я хотел бы привязать события ‹Key›, чтобы все с видимым эффектом заполнялось (например, a, 7 и *), в то время как любые клавиши без видимых эффектов имеют свой keysym вместо этого установлено представление (Return, Tabx, Shift_L и т. д.)

Если я привяжу «Key» к каждому из этих виджетов Entry, все, что имеет видимый event.char, будет напечатано дважды. Ничего с невидимкой нет. Если я привязываю ‹Key› к корню, этого не происходит.

Учитывая, что в моей фактической программе есть несколько кнопок и холст, не стоит ли привязывать ‹Key› к корню?
Если да, то как я могу привязать его к каждому виджету по отдельности и избежать двойного вывода чего-либо без пустого события. чар?

#!/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()

Результаты привязки к root
Результаты привязки к каждой записи


person ig-    schedule 24.04.2020    source источник
comment
Отвечает ли это на ваш вопрос? как-связать-собственные-события-в-tkinter-text-widget-after-it-will-binded-by-text- видж   -  person stovfl    schedule 24.04.2020
comment
используя ту же функцию set_key, что и выше, я могу добавить новый ключ привязки, который будет идти после .entry и Entry, но перед . и все. Это сработает, если я привяжу ‹key› к этому новому bindkey, но я не знаю, насколько мне это нравится, и мне интересно, есть ли способ, который меньше похож на то, что я переставляю tk внутренности, не понимая, что я делаю. делает   -  person ig-    schedule 24.04.2020


Ответы (1)


Учитывая, что в моей фактической программе есть несколько кнопок и холст, не стоит ли привязываться к 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

person Bryan Oakley    schedule 24.04.2020
comment
Благодарю вас! return "break" чтобы предотвратить привязку по умолчанию, это то, что я искал! И вы правы, я должен был сказать, что привязка к каждому виджету по отдельности не работает, как я хотел, но не то чтобы она не работала. Привязка по большей части работала. И спасибо за часть event.widget! - person ig-; 24.04.2020