So, i have a LED controlled by a Raspy, and also a basic GUI with just a push button, I want it to behave as follows:
When I execute light starts blinking, but the button does not show up. When I interrupt the program, the button shows up. Why?
from tkinter import *
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.output(8, False)
buttonPressed = False
master = Tk()
def callback():
GPIO.output(8, True)
buttonPressed = True
w = Button(master, text="Turn on light", command = callback)
w.pack()
while True:
if buttonPressed == False:
GPIO.output(8, True)
time.sleep(0.5)
GPIO.output(8, False)
time.sleep(0.5)
else:
GPIO.output(8, True)
I can't test it on RPi but I could be something like this.
Normal command=
can recognize only when you clicked button but it can't recognize when you released it - you need to bind events <ButtonPress>
and <ButtonRelease>
which will run functions on "mouse left button press"
and "mouse left button release"
I use after()
to run function with delay so I don't need sleep()
and while
which can block mainloop()
(and it can freeze all GUI).
And I don't need also while
loop because I run all inside on_press
and on_release
and later after()
runs turn_off_led
which use after()
to run turn_on_led
which use after()
to run again turn_off_led
so it works like loop.
import tkinter as tk # PEP8: `import *` is not preferred
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.output(8, False)
button_pressed = False # PEP8: preferred `lower_case_names`
# --- functions ---
def on_press(event):
global button_pressed
button_pressed = True
GPIO.output(8, True)
def on_release(event):
global button_pressed
button_pressed = False
GPIO.output(8, True)
# run after 500ms (0.5s) instead of `sleep`
master.after(500, blink_off)
def blink_off():
if not button_pressed:
GPIO.output(8, False)
# run after 500ms (0.5s) instead of `sleep`
master.after(500, blink_on)
def blink_on():
if not button_pressed:
GPIO.output(8, True)
# run after 500ms (0.5s) instead of `sleep`
master.after(500, blink_off)
# --- main ---
master = tk.Tk()
button = tk.Button(master, text="Turn on light")
button.pack()
# here "button" means "tk.Button" and "Button" means "mouse left button"
button.bind('<ButtonPress>', on_press) # mouse left button pressed on tk.Button
button.bind('<ButtonRelease>', on_release) # mouse left button released on tk.Button
# start blinking - it will use `after()` to loop
blink_on()
master.mainloop()