【问题标题】:Tkinter entrybox, not allowing typing and showing one string at a timeTkinter 输入框,不允许一次输入和显示一个字符串
【发布时间】:2019-09-22 14:41:00
【问题描述】:

我正在尝试制作一个输入框,当它获得焦点时获取键盘输入,并且只在框的中间显示该键名,没有闪烁的条并且不允许编辑。并且还将变量更改为键。

所以如果[ ] 是一个输入框。我输入F7,然后框应该显示[ F7 ],然后当我按下退格按钮时,框应该显示[ Backspace ]

在我的代码中,像F1F2 等特殊键甚至都没有给我正确的反馈,因为所有功能键都给我'',退格键给我'\x08'。如果所有键都显示不同的字符,我想我可以找到一种方法来链接字符和要打印的名称。但这种情况并非如此。像[1234| ] 这样的输入框类型不像[ 1 ]。而且我不知道如何在输入框中获取键名。

    def callback(event):
        key_input_entered.focus_set()
        print(repr(event.char))

    kb_frame = ttk.Frame(self.kb)
    kb_frame.grid(column=0, row=1, pady=(7, 19))
    ttk.Label(kb_frame, text='Enter Key').grid(column=0, row=0, pady=4)
    key_input = tk.StringVar()
    key_input_entered = ttk.Entry(kb_frame, width=15, textvariable=key_input)
    key_input_entered.grid(column=0, row=1)
    key_input_entered.bind('<Key>', callback)

【问题讨论】:

  • 我认为您需要创建一个键盘事件处理程序并使用它来填充 Text 小部件或类似的东西。

标签: python tkinter keyboard-events tkinter-entry


【解决方案1】:

要获得 Entry 小部件中的所有功能,您需要对其进行修改。

  1. Entry 小部件中取消绑定序列&lt;Key&gt; 以及&lt;BackSpace&gt;

  2. 通过配置justify='center'使文本居中对齐。

  3. 要获得所需的键名,您必须将&lt;Key&gt; 绑定到Entry 小部件并获取event.keysym,因为它会为您提供按下的键的名称。

  4. 1234563和“正常”状态,就像在函数 self._display(..) 中一样,当 Entry 小部件处于“只读”状态时,它不允许任何文本插入。

这是继承自 Entry 小部件的自定义类 Entry_Box

import tkinter as tk

class EntryBox(tk.Entry):
    def __init__(self, master=None, cnf={}, **kw):
        kw = tk._cnfmerge( (kw, cnf) )
        kw['justify'] = kw.get('justify', 'center')
        kw['state'] = 'readonly' 
        super(EntryBox, self).__init__(master=master, **kw)
        self.bind_class(self, '<Key>', self._display)

    def _display(self, evt):
        self['state'] = 'normal'
        self.delete('0', 'end')
        self.insert('0', str(evt.keysym))
        self['state'] = 'readonly'


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

代码简要说明:

tk._cnfmerge() 是 tkinter 库的内部函数,该函数的目的是将多个字典组合在一起。现在您可能想知道我们可以在没有此功能的情况下组合字典。是的,我们可以,但这样我们就不会出现任何错误,例如任何字典为 None 时。这是函数的source code

bind_classbind 函数类似,但它引用了内部类名称,例如 Entry 小部件具有像 &lt;Key&gt;, &lt;BackSpace&gt;, &lt;Return&gt;, ... 这样的绑定,它们是内部绑定,因此如果用户尝试绑定或取消绑定任何序列它不会干扰内部绑定,直到它们使用 unbind_class 和内部给出的相同类名(类名就像一个标签)。这个post可以更好的解释。

【讨论】:

  • 这就像我想要的那样工作。但除了_display function,我无法理解代码。我不知道tk.EnterEntryBox(): 内部做什么,也找不到tk._cnfmerge 的信息,也无法弄清楚self.unbind_class 中的Entry 指向什么。你能在顶层窗口中给我看一个例子吗?
  • 我设法在顶层窗口中获取了输入框。但我仍然不知道它是如何工作的。
  • 我更新了我的帖子,添加了一些重要信息和链接,以便您更好地了解事情的运作方式。
  • 不知道我理解对不对。这是否意味着self.unbind_class('Entry', '&lt;BackSpace&gt;') 让我使用来自tk.Enter 的绑定标签?那么为什么self.bind_class(self, '&lt;Key&gt;', self._display) 的类名中有selfclass Entrybox 可以使用bindtag &lt;key&gt; 呢?我评论了这两个self.unbind_class,它的工作原理是一样的。他们对程序做了什么?这可能很愚蠢,但我仍然不知道为什么这个类会在tk.Enter 内创建一个输入框,() ofclass EntryBox():
  • 另外,右 ctrl 和右 alt 键无法正常工作。它显示了两个节目???。我该如何解决这个问题?
猜你喜欢
  • 2017-12-09
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多