Стрелка вверх и вниз, вставка нежелательного символа в виджет tkinter.Entry - PullRequest
1 голос
/ 27 мая 2019

Следующий код создает приложение с одним виджетом Entry.При запуске на MacOS с использованием Python 3.7.3 из Homebrew, нажатие стрелки вверх или вниз внутри поля ввода приводит к вставке символа 0xF701:

Down key introduces character

import tkinter as tk

root = tk.Tk()
app = tk.Frame(master=root)
app.pack()

entry = tk.Entry(app)
entry.pack()

app.mainloop()

Этого не происходит с Anaconda Python, и я не смог найти никого другого, имеющего эту проблему.

Связывая print с событиями вверх и вниз, я смог увидеть, что символ, связанный с этими событиями, действительно 0xF700 и 0xF701.

entry.bind('<Down>', print)
entry.bind('<Up>', print)

Вывод после нажатия вверх и вниз:

<KeyPress event state=Mod3|Mod4 keysym=Up keycode=8320768 char='\uf700' delta=8320768 x=-5 y=-50>
<KeyPress event state=Mod3|Mod4 keysym=Down keycode=8255233 char='\uf701' delta=8255233 x=-5 y=-50>

В версии Anaconda Python вывод немного отличается:

<KeyPress event state=Mod3|Mod4 keysym=Up keycode=8320768 char='\uf700' x=-5 y=-50>
<KeyPress event state=Mod3|Mod4 keysym=Down keycode=8255233 char='\uf701' x=-5 y=-50>

Кто-нибудь знает опростое решение этой проблемы?

Ответы [ 2 ]

1 голос
/ 28 мая 2019

Причина, по которой вы получаете эти неизвестные символы в виджете Entry, заключается в том, что по какой-то причине коды символов "Вверх" (\ uf700) и "Вниз" ( \ uf701) стрелки печатают при запуске из доморощенного питона, но не с анакондой, не знаю, почему это так.

Вы можете попытаться увидеть себя, запустив этот код с любым из них.

root = Tk()
E = Entry(root)
E.bind('<Key>', lambda e: print(e.char))
E.pack()
root.mainloop()

Решение, которое я придумаю, состоит в том, чтобы перезаписать основную <Key> привязку Entry виджета, чтобы игнорировать «Вверх» и «Вниз» стрелки.

import tkinter as tk

class Entry(tk.Entry):
    def __init__(self, master=None, cnf={}, **kw):
        super(Entry, self).__init__(master=master, cnf=cnf, **kw)
        self.bind_class('Entry', '<Key>', self.add_char)

    def add_char(self, evt):
        if evt.char != '\uf701' and evt.char != '\uf700':
            self.insert('insert', evt.char)
            self.xview_moveto(1)

if __name__ == "__main__":
    root = tk.Tk()

    E = Entry(root)
    E.pack()

    root.mainloop()
1 голос
/ 27 мая 2019

Может ли помочь проверка заявки?Приведенный ниже код подтверждает, что результирующая строка в Entry содержит только символы в valid_chars.При необходимости можно написать более сложное правило проверки.

import tkinter as tk
import re

valid_chars = re.compile(r'^[0-9A-Za-z ]*$') # Accept Alphanumeric and Space

class ValidateEntry(tk.Entry):
    def __init__(self, parent, regex):
        self.valid = regex
        validate_cmd = (parent.register(self.validate),'%P') # %P pass the new string to validate
        super().__init__( parent, validate = 'key', validatecommand = validate_cmd)
        #  validate = 'key' runs the validation at each keystroke.

    def validate(self, new_str):
        if self.valid.match(new_str): return True
        return False

def do_key(ev):
    print(ev.widget, ev, entry.get())

root= tk.Tk()
root.title("Validation")
fram = tk.Frame(root)
fram.grid()

entry = ValidateEntry(fram, valid_chars)
entry.grid()
entry.bind('<Down>', do_key)
entry.bind('<Up>', do_key)

root.mainloop()

Это может быть излишним, но должно работать на всех платформах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...