Exactly as the question says. Text widgets have the <<Modified>> event, but Entry widgets don't appear to.
Exactly as the question says. Text widgets have the <<Modified>> event, but Entry widgets don't appear to.
You can also use the KeyRelease event that will be fired every time when the user clicks on the widget.
Than you can than filter for changes.
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()
I hope it helps.
I have been able to do what I needed using the <FocusOut> event. Here is a sample:
import tkinter
from tkinter import ttk
def doSomething(event):
text = event.widget.get()
print(text)
window = tkinter.Tk()
testEntry = ttk.Entry(window)
testEntry.bind('<FocusOut>', doSomething)
testEntry.grid(column=0,row=0)
thingEntry = ttk.Entry(window)
thingEntry.bind('<FocusOut>', doSomething)
thingEntry.grid(column=0,row=1)
startButton = ttk.Button(window,text='OK',command=lambda: print('click'))
startButton.grid(column=0,row=2, sticky='W')
window.mainloop()
print('Bye Bye')
The important part is:
def doSomething(event):
text = event.widget.get()
print(text)
testEntry.bind('<FocusOut>', doSomething)
Using Entry.bind(event,function) you can attach an event listener, in this case the doSomething function. This function gets one parameter, an Event object. In turn, you can read what’s in the Entry widget using event.widget.get().
Every time you leave an Entry, its value is printed. This includes when you click on the button. As you will see from the test, the button’s event is triggered after the Entry’s event,
I know other variant.
before i input the code, it could better explain path of coding: read here
and there is my code:
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()
there is 2 variant: by press button and enter to entry. now you can select any variant
I found using the built in TK Validation fits my beginner level of python skill better. Validation of an Entry element is not well documented in tkinter itself, you must use a register() method to set a callback , and by always returning True from the registered validation callback, you are able to get a notification.
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)
(illustrative code only)
Example answer here Interactively validating Entry widget content in tkinter , and some docs on the events here https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/entry-validation.html . It's not less code than using trace, but may be easier for some beginners to follow and to build on.
This is my take on this based on @Avi ba answer. Made it simpler by adding a setter and getter for text variable. Also avoided using StrinVar.
class CustomEntry(ttk.Entry):
def __init__(self, parent, valueChangeCallback=lambda x: print(x), **kwargs):
super().__init__(parent, **kwargs)
# bind function callback when value of the text is changed
self.bind("<KeyRelease>", lambda e: valueChangeCallback(self.text))
@property
def text(self) -> str:
return self.get()
@text.setter
def text(self, value) -> None:
self.delete(0, 'end')
self.insert(0, value)