帮助处理Python Entry小部件中的<key>事件
我正在用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"
所有修改过的行都用“这里!”标记出来了。