0
votes

In this UI there is 2 buttons and 1 entry box. Buttons named "Start Loop" and "Print".

When i write a text into the entry box, i should able to see it's print out when pressed the related button. What i am trying to do is, put that button press in a while loop. But the interesting part is trying to print a new entry in every 10 seconds.

When you entered a entry and press the "Start Loop" button, it becomes run. Meanwhile user interface window will froze. Can't write a new entry or press "Print" button. Even i use time.sleep function it still frozen. It prints old entry, but i want to write a new entry at every iteration. Check out the code:

import time
from tkinter import *

class tkin(Frame):
    def __init__(self,parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.UI()

    def UI(self):
        self.down = StringVar()
        self.down_entry = Entry(self, textvariable=self.down)
        self.down_entry.grid(row=2, column=0)


        self.start_loop_buuton = Button(text="Start Loop", command=self.loop_func)
        self.start_loop_buuton.place(x=10,y=40)
        self.print_func_button = Button(text="Print ", command=self.pprint)
        self.print_func_button.place(x=120,y=40)
        self.pack()

    def loop_func(self):
        start = time.time()
        while True:
            print("standart print out")
            end = time.time()
            if (end- start) >10:
                time.sleep(10)
                self.print_func_button.invoke()           ## press print_func_button
                start = time.time()
                

    def pprint(self):
        print("WHICH PRINT LINE I WANT TO PRINT IN LIKE EVERY 10 SECONDS")
        print(self.down.get())

def main():
    root = Tk()
    tkin(root)
    root.geometry("195x100+300+300")
    root.mainloop()

main()

Any advice would be nice. Thanks in advance.

2
You will have to put it in a separate thread otherwise You are interfering with tkinter's mainloop - Matiiss
Or You can use after() method - Matiiss
Also time.sleep() freezes the whole script - Matiiss

2 Answers

1
votes

this is how I would redefine Your method:

def loop_func(self):
        self.print_func_button.invoke()  # press print_func_button
        self.after(3000, self.loop_func)

time is in miliseconds so this will be 3 seconds

0
votes

In this example, i just separated the looping "loop_func()" using thread in Button function's argument of command. Like that:

import threading

...
...
...

self.start_loop_buuton = Button(text="Start Loop", command=threading.Thread(target=self.loop_func).start())

So, these two loops have been separated.