CMA
CMA

Reputation: 35

starting/stopping while loops with button in tkinter

By using two different buttons, I'm trying to start and stop a process based on a while loop that scans through patterns (actually just counting in this example). In the following code, I have tried to simplify and generalise the more complex process that occurs in the actual project I'm working on. As you can see by running the code, you can start the count by pressing the play button; when you press the stop button though, the process doesn't stop immediately. I have previously managed to make it work as desired, but while rewriting the code with an object oriented approach, nothing is working properly anymore. At the moment, I can't understand anymore if the problem is in the while loop construction or if I'm working with threads in the wrong way. Any suggestion is very welcome and appreciated!

from tkinter import *
import threading
import time

class gui:

    def __init__(self, window):

        #play button
        self.play_frame = Frame (master = window, relief = FLAT, borderwidth = 1)
        self.play_frame.grid (row = 0, column = 0, padx = 1, pady = 1)
        self.play_button = Button (self.play_frame, text = "play", fg = "blue", command = lambda: self.play(1))
        self.play_button.pack()
        #stop button
        self.stop_frame = Frame (master = window, relief = FLAT, borderwidth = 1)
        self.stop_frame.grid (row = 0, column = 2, padx = 1, pady = 1)
        self.stop_button = Button (self.stop_frame, text = "stop", fg = "red", command = lambda: self.play(0))
        self.stop_button.pack()

    def process(self, trig):
        self.trig = trig

        while True:
            if self.trig == 1:

                for i in range (10):
                    time.sleep(0.5)
                    print (i)


            elif self.trig == 0:
                print ("stopped...")
                break

    def play(self, switch):


        self.switch = int(switch)
        t1 = threading.Thread (target = self.process, args = [self.switch], daemon = True)
        t1.start()
        

root = Tk()

app = gui(root)
root.mainloop()

Upvotes: 2

Views: 1132

Answers (1)

coderoftheday
coderoftheday

Reputation: 2075

Just create a separate thread that receives a signal when to start and stop the countdown

from tkinter import *
import threading
import time


should_run = False
class a:
    def __init__(self):
        while True:
            if should_run:
                for i in range(10):
                    if not should_run:
                        print('Stopped...')
                        break
                    if should_run:
                        time.sleep(0.5)
                        print(i)

t1 = threading.Thread(target=a,daemon=True)
t1.start()

class gui:

    def __init__(self, window):

        # play button
        self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
        self.play_frame.grid(row=0, column=0, padx=1, pady=1)
        self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(True))
        self.play_button.pack()
        # stop button
        self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
        self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
        self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(False))
        self.stop_button.pack()


    def play(self, switch):
        global should_run
        should_run = switch



root = Tk()

app = gui(root)
root.mainloop()

Upvotes: 1

Related Questions