Tkinter дважды печатает символы при привязке к <Key> - PullRequest
0 голосов
/ 24 апреля 2020

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

Если я связываю с каждым из этих виджетов Entry, то все, что имеет видимый event.char double печать. Ничего с невидимым не делает. Если я привяжу к root, этого не произойдет.

Учитывая, что в моей настоящей программе есть несколько кнопок и холст, плохая идея привязать к root ?
Если так, как я могу привязать его к каждому виджету отдельно и избежать двойной печати чего-либо без пустого события .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()

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

1 Ответ

0 голосов
/ 24 апреля 2020

Учитывая, что моя настоящая программа имеет несколько кнопок и холст, плохая идея привязать к root?

Да, это плохая идея. Привязка к root означает, что это повлияет на каждый виджет.

Если это так, как я могу привязать его к каждому виджету индивидуально и избежать двойной печати чего-либо без пустого события.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"

Более подробное описание событий и привязок см. в следующем ответе: { ссылка }

...