Reputation: 428
I would like to filter dataset with a delay.
I have this basic layout:
import tkinter as tk
def filter(*args):
print('entry callback', 'changed %s' % str(args))
print('limit result set with', filter_input.get())
if __name__ == "__main__":
master = tk.Tk()
filter_input = tk.StringVar(value='') # filter mode
# filter_input.trace('w', filter) # simple trace triggers immediately
# filter_input.trace_variable('w', filter) # trace_variable as well
filter_input.trace_add('write', filter) # trace_add should replace previous (deprecated)
entry_field = tk.Entry(master, textvariable=filter_input)
entry_field.pack()
tk.mainloop()
I started with main Tkinter python page
I went through the main widget documentation
There are a bunch of more documentation around the globe, but I can't find anywhere any mention about a delay implemented. Can anyone help me to find out, if there is possible to call the filter function after some defined amount of time? Maybe another wrapper function could help?
EDIT:
It looks like I need to clear out the desired functionality. This is somehow what I am after but I need a delay instead of "user-stops-typing" activity.
Upvotes: 1
Views: 491
Reputation: 15098
If you just want to call the function with a delay then use after(ms,func)
to call the function after ms
milliseconds. So your function could be like:
def filter(*args):
# print(f'entry callback changed {str(args)}')
print(f'limit result set with {filter_input.get()}')
master.after(1000,filter) # Call this function every 1000 millisecond or 1 second
if __name__ == "__main__":
master = tk.Tk()
....
filter() # Call the function initially
tk.mainloop()
So you can also get rid of StringVar
here as you are using after()
and nothing else. If you want to end this after()
loop, then use after_cancel(id)
.
EDIT:
If you want to see the input with just a delay once each time the window is open, then try this:
first = True
def show():
global first
if first and entry_field.get():
first = False
master.after(3000,lambda: print(entry_field.get()))
if __name__ == "__main__":
master = tk.Tk()
......
entry_field.bind('<Key>',lambda e: show())
EDIT 2: This will call the function also when the box is cleared and typed again:
first = True
def show():
global first
if entry_field.get():
if first:
first = False
master.after(3000,lambda: print(entry_field.get()))
else:
first = True
Upvotes: 2