【问题标题】:Up and down arrow inserting unwanted character in tkinter.Entry widget向上和向下箭头在 tkinter.Entry 小部件中插入不需要的字符
【发布时间】:2019-05-27 04:37:11
【问题描述】:

以下代码生成一个带有单个 Entry 小部件的应用。在 MacOS 上使用来自 Homebrew 的 Python 3.7.3 运行时,在输入框内按向上或向下箭头会插入一个字符 0xF701:

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 绑定到up 和down 事件,我已经能够看到与这些事件关联的字符确实是0xF7000xF701

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>

有人知道这个问题的简单解决方案吗?

【问题讨论】:

  • 我在自己的 mac 上运行了这个,我遇到了同样的问题,这可能只是 Mac OS 上的 tkinter 的问题。我会想办法解决的。
  • @MatthewG:这与在 anaconda 上与 python 捆绑在一起的 tkinter 包和在 Homebrew 上安装的 python 有关。它们绝对不一样。

标签: python-3.x macos tkinter


【解决方案1】:

验证条目有帮助吗?下面的代码验证 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()

这可能有点矫枉过正,但应该适用于所有平台。

【讨论】:

    【解决方案2】:

    为什么您会在 Entry 小部件中获取这些未知字符的版本是因为出于某种原因 “Up” (\uf700) 和 “Down”的字符代码> (\uf701) arrows prints when run from homebrew python but not with anaconda python不知道为什么。

    您可以尝试通过使用其中任何一个运行此代码来了解自己。

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

    我想出的解决方案是覆盖Entry 小部件的主要&lt;Key&gt; 绑定以忽略“向上”“向下” 箭头。

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

    【讨论】:

    • 只要您在末尾添加字符,它就可以工作。如果您尝试将“Fred”更改为“Freed”,您最终会得到“Fred”。
    • @TlsChris:感谢您指出我将索引更改为“插入”。
    • 这比我的回答要轻松。我从未尝试在条目中使用插入。我也喜欢将 cnf 和关键字传递给 super 的方式。
    • @TlsChris:您也可以将cnfkw 带到super(),或者只使用**kw 并更新validatevalidate_cmd,就像kw['validate'] = 'key'。 ..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多