Tkinter,Entry小部件,可以检测输入文本吗?

时间:2013-10-02 23:06:45

标签: python user-interface widget tkinter

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

3 个答案:

答案 0 :(得分:6)

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

您可以创建StringVar,将其附加到Entry,然后trace进行更改;你可以bind所有相关事件;或者您可以添加在序列中的几个不同点中的任何一个点火的validation command。他们都做了稍微不同的事情。

当用户输入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文档中的任何位置都没有描述,所以你需要去the Tcl/Tk docs。您想要的最常见的事情是建议的新文本作为参数,为此,请使用(vcmd, '%P')


无论如何,你一定要玩各种不同的东西,看看每种机制给你的东西。在键入之前移动光标或选择部分字符串,使用键盘和鼠标粘贴,拖放选择,点击各种特殊键等。


*我将忽略这一步,因为它在不同版本的Tk中有所不同,并且无论如何都不是很有用。如果您确实需要修改事件,最好使用Text窗口小部件并绑定<<Modified>>

答案 1 :(得分:5)

每次在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属性,该脚本将打印每个按键的内容。

答案 2 :(得分:1)

如果你只需要做一些简单的事情而不使用跟踪模块,你可以试试

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