帮助处理Python Entry小部件中的<key>事件

1 投票
2 回答
2031 浏览
提问于 2025-04-11 09:33

我正在用Python写一些代码,但在尝试获取一个输入框(Entry widget)的内容时遇到了问题。

具体来说,我想限制可以输入的字符数量,所以我试图在达到特定字符数(这里是2个字符)时清空这个输入框。但看起来我总是漏掉最后输入的那个字符。我在打印输出中加上了这个漏掉的字符。

下面是示例代码:

from Tkinter import *
class sampleFrame:
    def __init__(self, master):
        self.__frame = Frame(master)
        self.__frame.pack()
    def get_frame(self):
        return self.__frame


class sampleClass:
    def __init__(self, master):
        self.__aLabel = Label(master,text="aLabel", width=10)
        self.__aLabel.pack(side=LEFT)
        self.__aEntry = Entry (master, width=2)
        self.__aEntry.bind('<Key>', lambda event: self.callback(event, self.__aEntry))
        self.__aEntry.pack(side=LEFT)

    def callback(self, event, widgetName):
        self.__value = widgetName.get()+event.char
        print self.__value
        if len(self.__value)>2:
            widgetName.delete(2,4)





root = Tk()
aSampleFrame = sampleFrame(root)
aSampleClass = sampleClass(aSampleFrame.get_frame())
root.mainloop()

任何帮助都会非常感谢!

提前谢谢你!

2 个回答

1

更具体一点,Tk的控件有一种叫做“绑定标签”的东西。当一个事件发生时,系统会按照顺序检查控件上的每个绑定标签,看它们是否有绑定的操作。默认情况下,一个控件的绑定标签包括这个控件本身、控件的类别、根控件和“所有”。所以,控件的绑定会在默认绑定之前执行。一旦你的绑定被处理完,你可以通过返回一个“break”来阻止后续的绑定标签被考虑。

这意味着什么呢?如果你在控件上设置了一个绑定,控件的类别、根窗口和“所有”的绑定也可能会被触发。此外,你在控件上设置的任何绑定会在类别绑定之前执行,而类别绑定是默认行为发生的地方(比如插入一个字符)。在你想在默认行为之后处理事件的情况下,了解这一点是很重要的。

3

一开始,当你删除某个东西后,事件会继续正常处理,也就是说,字符会被插入。你需要告诉Tkinter这个事件应该被忽略。

所以在你上面的代码中,添加标记的那一行:

if len(self.__value) > 2:
    widgetName.delete(2,4)
    return "break" # add this line

另一方面,为什么要通过lambda呢?其实事件有一个叫做.widget的属性,你可以直接使用它。所以你可以把你的代码改成:

    self.__aEntry.bind('<Key>', self.callback) # ※ here!
    self.__aEntry.pack(side=LEFT)

def callback(self, event):
    self.__value = event.widget.get()+event.char # ※ here!
    print self.__value
    if len(self.__value)>2:
        event.widget.delete(2,4) # ※ here!
        return "break"

所有修改过的行都用“这里!”标记出来了。

撰写回答