Python advice using delays with tkinter
Question: I have created GUI using tkinter, which will run on the RaspberryPi and will
perform various actions such as lighting LEDs. The problem I have is toggling
an LED on and off using the root.after scheduling as if I use time.sleep(),
the GUI will freeze while in this sleep. Here is my code, below I want to
replace time.sleep() with some kind of delay roughly 500ms.

    
    
    def toggleLED(root,period=0):
        if (period <15) and (Status is "On"):
                GPIO.output(11, True)
                time.sleep(0.5) #Needs to be replaced as causing GUI to freeze
                GPIO.output(11, False)
                root.after(1000, lambda: toggleLED(root, period)) #schedule task every 1 second while condition is true
        elif (Status == "Off"):
                print("Lights have been switched off")
        else:
                GPIO.output(11, True)
    

thanks

This is one solution, but it seems very messy:

    
    
    def toggleLED(root,period=0):
        global Flash
        while (period <30) and (Status is "On"):
                if (Flash is True):
                        GPIO.output(11, False)
                        Flash = False
                        break
                elif (Flash is False):
                        GPIO.output(11, True)
                        Flash = True
                        break
                else:
                        break
        if (period <30) and (Status == "On"):
                period +=1
                print(period)
                root.after(500, lambda: toggleLED(root, period))
        elif (Status == "Off"):
               print("Lights have been switched off")
        else:
               GPIO.output(11, True)
    


Answer: Part of the problem is your while loop -- you don't need any sort of loop
since you have the event loop.

Here's an example of toggling a label every 500ms for 30 seconds:

    
    
    import Tkinter as tk
    
    class Example(tk.Frame):
    
        def __init__(self, *args, **kwargs):
            tk.Frame.__init__(self, *args, **kwargs)
            self._job_id = None
    
            self.led = tk.Label(self, width=1, borderwidth=2, relief="groove")
            self.start_button = tk.Button(self, text="start", command=self.start)
            self.stop_button = tk.Button(self, text="stop", command=self.stop)
    
            self.start_button.pack(side="top")
            self.stop_button.pack(side="top")
            self.led.pack(side="top")
    
        def stop(self):
            if self._job_id is not None:
                self.after_cancel(self._job_id)
                self._job_id = None
                self.led.configure(background="#ffffff")
    
        def start(self):
            self._job_id = self.after(500, lambda: self.toggle(60))
    
        def toggle(self, counter):
            bg = self.led.cget("background")
            bg = "#ffffff" if bg == "#ff0000" else "#ff0000"
            self.led.configure(background=bg)
            if counter > 1:
                self._job_id = self.after(500, lambda: self.toggle(counter-1))
    
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
    

