如何在修改Tkinter Entry小部件时获取事件回调?

bfo*_*ops 46 python tkinter

正如问题所说的那样.Text小部件有<<Modified>>事件,但Entry小部件似乎没有.

Ste*_*ski 69

将Tkinter StringVar添加到Entry小部件中.使用trace方法将回调绑定到StringVar.

from Tkinter import *

def callback(sv):
    print sv.get()

root = Tk()
sv = StringVar()
sv.trace("w", lambda name, index, mode, sv=sv: callback(sv))
e = Entry(root, textvariable=sv)
e.pack()
root.mainloop()  
Run Code Online (Sandbox Code Playgroud)


Mat*_*aws 24

在撰写本文时(2017年,Python 3.6,tkinter版本8.6.6),文档建议.trace不推荐使用.建议的表格现在似乎是:

sv.trace_add("write", callback)
Run Code Online (Sandbox Code Playgroud)

如果您希望在更改变量时通知,则此方法非常有效.但是,我的应用程序只是在用户完成编辑文本时才想要通知.我发现支持"验证"机制在这里工作得很好:

from tkinter import *

root = Tk()
sv = StringVar()

def callback():
    print(sv.get())
    return True

e = Entry(root, textvariable=sv, validate="focusout", validatecommand=callback)
e.grid()
e = Entry(root)
e.grid()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

callback当条目小部件失去焦点时,这将调用(我添加了第二个条目小部件,因此第一个小部件实际上可能失去焦点!)


Dav*_*ave 10

谢谢史蒂文!罗素欧文的Tkinter的民俗介绍了如何直接从名称参数(PY_VAR#)使用globalgetvar()得到STRINGVAR值,而不是如何将名称映射到一个小部件.你改变回调算法的lambda方法就像魔法一样(至少对于Python新手来说).

当有多个条目时,通常不仅需要知道值,还要知道哪个条目已更改.稍微扩展了Steven的示例,以下(Python3)传递一个索引,该索引可用于跟踪多个条目.

from tkinter import Tk, Frame, Label, Entry, StringVar

class Fruitlist:
    def entryupdate(self, sv, i):
        print(sv, i, self.fruit[i], sv.get())

    def __init__(self, root):
        cf = Frame(root)
        cf.pack()
        self.string_vars = []
        self.fruit = ("Apple", "Banana", "Cherry", "Date")
        for f in self.fruit:
            i = len(self.string_vars)
            self.string_vars.append(StringVar())
            self.string_vars[i].trace("w", lambda name, index, mode, var=self.string_vars[i], i=i:
                              self.entryupdate(var, i))
            Label(cf, text=f).grid(column=2, row=i)
            Entry(cf, width=6, textvariable=self.string_vars[i]).grid(column=4, row=i)

root = Tk()
root.title("EntryUpdate")
app = Fruitlist(root)
root.mainloop() 
Run Code Online (Sandbox Code Playgroud)


Avi*_* ba 6

您还可以使用每次用户单击小部件时都会触发的 KeyRelease 事件。
比您可以过滤更改。

from tkinter import * 
from tkinter import ttk

class GUI():                              
    def __init__(self):  
        self.root = Tk()
        self.sv = StringVar() 
        self.prevlaue=''
        #entry
        self.entry = ttk.Entry(self.root, width=30, textvariable =self.sv)
        self.entry.grid(pady=20,padx=20) 
        self.entry.bind("<KeyRelease>", self.OnEntryClick) #keyup                  
        self.root.mainloop()       

    def OnEntryClick(self, event):
        value=self.sv.get().strip()
        changed = True if self.prevlaue != value else False
        print(value, 'Text has changed ? {}'.format(changed))
        self.prevlaue = value

#create the gui
GUI()
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助。


Man*_*ngo 5

我已经能够利用该<FocusOut>事件做我需要做的事情。这是一个示例:

\n
import tkinter\nfrom tkinter import ttk\n\ndef doSomething(event):\n    text = event.widget.get()\n    print(text)\n\nwindow = tkinter.Tk()\ntestEntry = ttk.Entry(window)\ntestEntry.bind(\'<FocusOut>\', doSomething)\ntestEntry.grid(column=0,row=0)\nthingEntry = ttk.Entry(window)\nthingEntry.bind(\'<FocusOut>\', doSomething)\nthingEntry.grid(column=0,row=1)\nstartButton = ttk.Button(window,text=\'OK\',command=lambda: print(\'click\'))\nstartButton.grid(column=0,row=2, sticky=\'W\')\n\nwindow.mainloop()\nprint(\'Bye Bye\')\n
Run Code Online (Sandbox Code Playgroud)\n

重要的部分是:

\n
def doSomething(event):\n    text = event.widget.get()\n    print(text)\n\ntestEntry.bind(\'<FocusOut>\', doSomething)\n
Run Code Online (Sandbox Code Playgroud)\n

使用Entry.bind(event,function)您可以附加一个事件监听器,在本例中是doSomething函数。该函数获取一个参数,一个Event对象。反过来,您可以Entry使用 读取小部件中的内容\xe2\x80\x99s event.widget.get()

\n

每次您离开 时Entry,都会打印它的值。这包括当您单击按钮时。从测试中可以看到,button\xe2\x80\x99s事件是在Entry\xe2\x80\x99s事件之后触发的,

\n