0

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)
2
  • Your solution can be cleaned by removing duplicate code and unnecessary blocks. However, what is the result you want to achieve? Toggling the light 30 times? Commented Mar 25, 2013 at 16:47
  • Yes the light should toggle 30 times within a 15 second period. Commented Mar 25, 2013 at 18:57

1 Answer 1

1

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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.