9

我在一个简单的计算器上有一个条目小部件。用户可以选择通过键盘输入方程式。我想知道是否有一种方法可以检测输入到 Entry 小部件中的字符(在我的情况下来自键盘)。所以,焦点在小部件上,用户按下“4”,它出现在小部件上......我可以检测到这个行为,用于记录输入的基本目的吗?

4

3 回答 3

11

每次在 Tkinter 窗口中按下一个键时,Tkinter.Event都会创建一个实例。您需要做的就是访问该实例。这是一个简单的脚本,演示了如何:

from Tkinter import Tk, Entry

root = Tk()

def click(key):
    # print the key that was pressed
    print key.char

entry = Entry()
entry.grid()
# Bind entry to any keypress
entry.bind("<Key>", click)

root.mainloop()

key(作为一个Tkinter.Event实例)包含许多不同的属性,可用于在按下的键上获取几乎任何类型的数据。我选择在.char这里使用属性,它将让脚本打印每个按键是什么。

于 2013-10-02T23:17:43.697 回答
8

是的。事实上,有几种不同的方法可以做到这一点。

您可以创建一个StringVar,将其附加到Entry,并trace进行更改;你可以bind所有相关的事件;或者您可以添加一个验证命令,该命令在序列中的几个不同点中的任何一个处触发。他们都做略有不同的事情。

当用户键入4时,会出现一个仅包含 的键事件4(这不能让您区分用户是添加4到末尾,还是在中间,或者替换整个选定的单词,或者……),然后是使用旧文本触发修改事件,* 然后使用(提议的)新文本调用“key”或“all”验证函数,并使用(接受的)新文本更新变量(除非返回验证函数false,在这种情况下,invalidcommand将改为调用)。


我不知道你想要哪一个,所以让我们把它们都展示出来,你可以和它们一起玩,然后选择你想要的。

import Tkinter as tk

root = tk.Tk()

def validate(newtext):
    print('validate: {}'.format(newtext))
    return True
vcmd = root.register(validate)

def key(event):
    print('key: {}'.format(event.char))

def var(*args):
    print('var: {} (args {})'.format(svar.get(), args))
svar = tk.StringVar()
svar.trace('w', var)

entry = tk.Entry(root,
                 textvariable=svar, 
                 validate="key", validatecommand=(vcmd, '%P'))
entry.bind('<Key>', key)
entry.pack()
root.mainloop()

变量跟踪回调的语法有点复杂,并且在 Tkinter 中没有很好的记录;如果您想知道前两个参数的含义,您需要阅读 Tcl/Tk 文档,并了解 Tkinter 如何将您的特定名称映射StringVar到 Tcl 名称'PY_VAR0'……实际上,为每个变量构建一个单独的函数要容易得多,并且要跟踪的模式,并忽略 args。

验证函数的语法比我展示的更复杂,也更灵活。例如,您可以获得插入的文本(在粘贴操作的情况下可以是多个字符)、它的位置以及各种其他的东西......但是这些都没有在 Tkinter 文档的任何地方描述,所以你将需要去Tcl/Tk 文档。您最想要的是将提议的新文本作为论据,为此,请使用(vcmd, '%P').


无论如何,您绝对应该尝试做各种不同的事情,看看每种机制能给您带来什么。在键入之前移动光标或选择部分字符串,用键盘和鼠标粘贴,拖放选择,点击各种特殊键等。


* 我将忽略这一步,因为它在不同版本的 Tk 中是不同的,反正不是很有用。在您确实需要修改事件的情况下,使用Text小部件和绑定可能会更好<<Modified>>

于 2013-10-02T23:15:20.443 回答
3

如果您只需要在不使用跟踪模块的情况下做一些简单的事情,您可以尝试

    def objchangetext(self, textwidget):
        print(textwidget.get())  #print text out to terminal

    text1 = tk.Entry(tk.Tk()) 
    text1.bind("<KeyRelease>", lambda event, arg=(0): objchangetext(text1)) 
于 2020-12-30T12:06:11.940 回答