ankit kumar
ankit kumar

Reputation: 87

python script runs after x seconds but when tkinter code inserted it runs only once

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

Answers (2)

1966bc
1966bc

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

NemoMeMeliorEst
NemoMeMeliorEst

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

Related Questions