I needed a delay before calling a function and getting its return value. But time.sleep
is freezing the tkinter GUI so i used tkinter.after
. tkinter.after
is working and won't freeze the window, but I cannot get the return value of the function that I've called. Because after I delayed and got the returned value, I've to return it again to the other function that called this function.
I've been struggling with this, please if any of you know any solutions, help me
This is the basic example of whats going on
import tkinter as tk
from time import sleep
def getvalue():
value = "haha"
sleep(3)
return value
def printvalue():
value = getvalue()
print(value)
app = tk.Tk()
app.geometry("500x300")
button = tk.Button(app, text="print value", command=printvalue)
button.pack()
app.mainloop()
For this simple example I would use tkinter.after()
to run function with delay. And all code afer getting data I would move to second function which is executed by tkinter.after()
.
But your real code can be more complex and it can be hard to split it.
import tkinter as tk
def getvalue():
return "haha"
def second_part(other):
print('after delay')
value = getvalue()
# code moved from first part
print('value:', value)
print('other:', other)
button['text'] = value
def print_value():
# first part makes some calculation
other_variable = 'some value'
print('before delay')
# run function with delay and send all data from first part
app.after(3000, second_part, other_variable)
# rest of code moved to second_part
app = tk.Tk()
button = tk.Button(app, text="print value", command=print_value)
button.pack()
app.mainloop()
EDIT: If you have problem to use tkinter.after()
then you can try to use Thread
to run print_value
which will have to wait for getvalue()
.
But Thread
sometimes may have problem to access GUI widgets in main thread.
import tkinter as tk
from time import sleep
import threading
def getvalue():
sleep(3)
return "haha"
def print_value():
# first part makes some calculation
other_variable = 'some value'
print('before delay')
value = getvalue()
print('after delay')
print('value:', value)
print('other:', other_variable)
button['text'] = value
def start_thread():
t = threading.Thread(target=print_value)
t.start()
app = tk.Tk()
button = tk.Button(app, text="print value", command=start_thread)
button.pack()
app.mainloop()
I was thinking about asyncio
which has non-blocking asyncio.sleep()
but asyncio
needs to run own loop which would block mainloop()
so it would have to run in Thread
.