ronan635
ronan635

Reputation: 33

Python Tkinter, Stop a threading function

I'm currently developing a GUI for a 3D printer and I'm having a problem of how to stop a threading function. I want to be able to click a button that has another function within my GUI that will stop the threading function from sending strings of G-code across the serial port. Currently the function has threading incorporated to allow other functions to be triggered during printing. I would greatly appreciate some advice on how I would incorporate this stop feature.

Below is the function that opens a G-code file and sends each line across the serial port.

def printFile():
def callback():
    f = open(entryBox2.get(), 'r');
    for line in f:
        l = line.strip('\r')
        ser.write("<" + l + ">")
        while True:
            response = ser.read()
            if (response == 'a'):
                break
t = threading.Thread(target=callback)
t.start()

Upvotes: 3

Views: 7298

Answers (2)

Roland Smith
Roland Smith

Reputation: 43495

Use a global variable as a condition for the thread to stop.

send_gcode = True

def printFile():
    def print_thread():
        f = open(entryBox2.get(), 'r');
        for line in f:
            if not send_gcode:
                break
            l = line.strip('\r')
            ser.write("<" + l + ">")
            while True:
                response = ser.read()
                if (response == 'a'):
                    break
    t = threading.Thread(target=print_thread)
    send_gcode = True
    t.start()

The thread will run until send_gcode is set to False (by e.g. a callback for a button:

def stop_callback(event):
    global send_gcode
    send_gcode = False

Upvotes: 0

Novel
Novel

Reputation: 13729

Threads cannot be stopped, they have to stop themselves. So you need to send a signal to the thread that it's time to stop. This is usually done with an Event.

stop_event = threading.Event()
def callback():
    f = open(entryBox2.get(), 'r');
    for line in f:
        l = line.strip('\r')
        ser.write("<" + l + ">")
        while True:
            response = ser.read()
            if (response == 'a'):
                break
            if stop_event.is_set():
                break
t = threading.Thread(target=callback)
t.start()

Now if you set the event elsewhere in your code:

stop_event.set()

The thread will notice that, break the loop and die.

Upvotes: 6

Related Questions