Reputation: 87
What is the best way to repeatedly execute a function every x seconds in Python?
i have tried the solutions posted on above links but none helped me to achieve the desired result.
the code above prints "Doing stuff..." on console many times as per seconds mentioned i.e. 5 but when i add the line of window() which is a tkinter code for displaying a message the code runs just once and not anytime again .
please help . i want to run the tkinter code again and again on specific time as per system clock but now i am just trying to execute it after x amounts of seconds .
any help would really mean a lot to me.Thanks
Upvotes: 1
Views: 373
Reputation: 1308
I think you need thread and queue...let me show a little demo.
I've set time.sleep(1) per seconds in the thead class.
In this matter you get two advantages, first repet your funcion any times
you desire and second your program never freeze it self.
import tkinter as tk
import threading
import queue
import datetime
import time
class MyThread(threading.Thread):
def __init__(self, queue,):
threading.Thread.__init__(self)
self.queue = queue
self.check = True
def stop(self):
self.check = False
def run(self):
while self.check:
x = "Doing stuff.. "
y = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
msg = x+y
time.sleep(1)
self.queue.put(msg)
class App(tk.Frame):
def __init__(self,):
super().__init__()
self.master.title("Hello World")
self.master.protocol("WM_DELETE_WINDOW",self.on_close)
self.queue = queue.Queue()
self.my_thread = None
self.init_ui()
def init_ui(self):
self.f = tk.Frame()
w = tk.Frame()
tk.Button(w, text="Start", command=self.launch_thread).pack()
tk.Button(w, text="Stop", command=self.stop_thread).pack()
tk.Button(w, text="Close", command=self.on_close).pack()
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
self.f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)
def launch_thread(self):
if (threading.active_count()!=0):
self.my_thread = MyThread(self.queue)
self.my_thread.start()
self.periodiccall()
def stop_thread(self):
if(threading.active_count()!=1):
self.my_thread.stop()
def periodiccall(self):
self.checkqueue()
if self.my_thread.is_alive():
self.after(1, self.periodiccall)
else:
pass
def checkqueue(self):
while self.queue.qsize():
try:
ret = self.queue.get(0)
msg = "%s"%(ret)
print(msg)
except queue.Empty:
pass
def on_close(self):
if(threading.active_count()!=1):
self.my_thread.stop()
self.master.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
Upvotes: 0
Reputation: 561
search for tkinter .after method.
This will alow you to run a command every x seconds.
The problem your tkinter code runs only once, is since its set up first and then goes into a loop, (root.mainloop()) , hence never returning to your code to display anything again.
Example : tkinter: how to use after method
Upvotes: 1