Search code examples
pythonpython-3.xuser-interfacetkinterpython-multithreading

Tkinter- How to stop a loop that is in another file with a stop button?


I want to stop a loop when I press a button. If I do it all in the same files I don´t have a problem but when I put the loop as a routine from another file It doesn´t work and I don´t know why. I hope you can help me! Thanks!!

First of all, this is subroutine.py, the file where is the loop allocated

subroutine.py

def routine (pressed):
    while True:
        print ("hello")
        
        if pressed== 1:   
            break   #Break while loop when stop = 1

And this is the "main" file

import tkinter as tk
import threading
import subroutine

pressed = 0

def Start_Scan():
    global pressed
    pressed = 0
        # Create and launch a thread 
    t = threading.Thread (target = subroutine.routine (pressed))
    t.start()


def Stop():
    global pressed
    pressed = 1

#main
master = tk.Tk()

app = tk.Frame(master)
app.grid()

start = tk.Button(app, text="Start Scan",command=Start_Scan)
stop = tk.Button(app, text="Stop",command=Stop)

start.grid()
stop.grid()

app.mainloop()

I use thread and a global variable, I thought about not using a global variable but I didn't find a way for the two threads to communicate that was not blocking. Thanks!!


Solution

  • You can use threading.Events to pass a flag between the main thread and the worker thread

    # main.py
    stop_event = threading.Event()
    
    
    def Start_Scan():
       # Create and launch a thread 
        t = threading.Thread (
            target=subroutine.routine,
            args=(stop_event,)  # pass the Event object to the worker target
        )
        t.start()
    
    
    def Stop():
        stop_event.set()
    

    Just update your subroutine to keep an eye on that event

    # subroutine.py
    def routine(stop_event):
        while not stop_event.is_set():  # loop until the Event is 'set'
            print ("hello")