正如问题所说。 Text
个小部件有<<Modified>>
个事件,但Entry
个小部件似乎没有。
答案 0 :(得分:61)
将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()
答案 1 :(得分:16)
在撰写本文时(2017年,Python 3.6,tkinter版本8.6.6),文档建议不推荐使用.trace
。建议的表格现在似乎是:
sv.trace_add("write", callback)
如果您希望在更改变量时通知,则此方法非常有效。但是,我的应用程序只是在用户完成编辑文本时才想要通知。我发现了&#34;验证&#34;机制在这里运作良好:
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()
每当条目小部件失去焦点时,这将调用callback
(我添加了第二个条目小部件,因此第一个小部件实际上可能失去焦点!)
答案 2 :(得分:9)
谢谢史蒂文! Russell Owen的Tkinter Folklore解释了如何使用globalgetvar()直接从name参数(PY_VAR#)获取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()
答案 3 :(得分:0)
我知道其他变种。
在输入代码之前,它可以更好地解释编码路径:阅读here
并且有我的代码:
from Tkinter import *
class ttt:
def __init__(self):
self.str1 = StringVar()
self.e1 = Entry(root, textvariable=self.str1)
self.str1.trace('w', self.callback_1)
self.e1.pack()
self.str2 = StringVar()
self.e2 = Entry(root, textvariable=self.str2, state='readonly')
self.e2.pack()
self.str3 = StringVar()
self.e3 = Entry(root, textvariable=self.str3, state='readonly')
self.e3.pack()
bt = Button(root, text = 'ещё', command = self.callback_2)
bt.pack()
def callback_1(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str2.set(int(tmp) * 6)
print self.str2.get()
def callback_2(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str3.set(int(tmp) * 6)
print self.str3.get()
root = Tk()
t = ttt()
root.mainloop()
有两种变体:按下按钮并进入输入。 现在您可以选择任何变体
答案 4 :(得分:0)
我使用Python 3.6并且无法使.trace工作。以下代码允许接受或编辑StringVar的默认值。按下返回键时调用on_changed。
from tkinter import Tk, LEFT, BOTH, StringVar
from tkinter.ttk import Entry, Frame
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Entry")
self.pack(fill=BOTH, expand=1)
self.contents = StringVar()
# give the StringVar a default value
self.contents.set('test')
self.entry = Entry(self)
self.entry.pack(side=LEFT, padx=15)
self.entry["textvariable"] = self.contents
self.entry.bind('<Key-Return>', self.on_changed)
def on_changed(self, event):
print('contents: {}'.format(self.contents.get()))
return True
def main():
root = Tk()
ex = Example(root)
root.geometry("250x100+300+300")
root.mainloop()
if __name__ == '__main__':
main()
答案 5 :(得分:0)
您还可以使用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()
希望对您有帮助。
答案 6 :(得分:0)
为什么需要知道Entry修改的时间?
可能您需要其他行为:
在这种情况下,您只需处理Enter键
self.entry.bind('<Return>', self.on_enter)
def on_enter(self, key_info):
text = self.entry.get()
答案 7 :(得分:0)
我发现使用内置的TK验证更适合我的python初学者水平。 tkinter本身并未很好地记录Entry元素的验证,您必须使用register()方法设置回调,并且通过始终从已注册的验证回调中返回True,您可以通知。
def filter_callback(self,new_value):
print(new_value)
# must return true since we want the validation events to keep coming
return(True)
def __init__(self,root)
self.edit_filter = ttk.Entry(root)
# %d = Type of action (1=insert, 0=delete, -1 for others)
# %i = index of char string to be inserted/deleted, or -1
# %P = value of the entry if the edit is allowed
# %s = value of entry prior to editing
# %S = the text string being inserted or deleted, if any
# %v = the type of validation that is currently set
# %V = the type of validation that triggered the callback
# (key, focusin, focusout, forced)
# %W = the tk name of the widget
vcmd = (self.edit_filter.register(self.filter_callback), "%P")
# notify key presses only
self.edit_filter.config(validate = "key", validatecommand = vcmd)
(仅说明性代码)
此处的示例答案Interactively validating Entry widget content in tkinter,以及此处事件的一些文档https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/entry-validation.html。它的代码不少于使用trace,但对于某些初学者而言,可能更容易遵循和建立。