You should use gpiozero, which has already event driven callbacks and it's own background thread.
Example-Code:
Example-Code:
import os from tkinter import Button, Label, Tk from gpiozero import Button as GPIO_Button from gpiozero.pins.mock import MockFactory from PIL import Image from PIL.ImageTk import PhotoImage # There is Button from tkinter already imported # renaming Button to GPIO_Button # MockFactory is to test without GPIO (real Hardware) if not os.environ.get("DISPLAY", ""): print("no display found. Using :0.0") os.environ["DISPLAY"] = ":0.0" def set_red_image(): """ Callback function for gpio Button """ label["image"] = red_img def set_white_image(): """ Callback function for gpio Button """ label["image"] = white_img def drive_low(): """ This function is for testing without GPIO. """ print("Setting GPIO to low state") gpio_pin = mock_factory.pins[pin] gpio_pin.drive_low() # call drive high after 2 seconds root.after(2000, drive_high) def drive_high(): """ This function is for testing without GPIO. """ print("Setting GPIO to high state") gpio_pin = mock_factory.pins[pin] gpio_pin.drive_high() # call drive_low after one second root.after(1000, drive_low) if __name__ == "__main__": pin = 21 # for testing without gpio mock_factory = MockFactory() # end button = GPIO_Button(pin, pin_factory=mock_factory) # button = GPIO_Button(pin) # <- with real gpio # the library has an own background thread, # which handles incomming events like positive edge or negative edge # https://gpiozero.readthedocs.io/en/stable/recipes.html#button button.when_pressed = set_red_image button.when_released = set_white_image # when_pressed calls set_red_image # when_released calls set_white_image root = Tk() root.geometry("800x600") # placeholder images # Hint: PhotoImage requires the master (root). # Don't create instances of PhotoImage # before root was created white_img = PhotoImage( Image.new(mode="RGB", size=(200, 200), color=(255, 255, 255)) ) red_img = PhotoImage(Image.new(mode="RGB", size=(200, 200), color=(255, 0, 0))) # creating the label once is enough # you can change the label afterwards it was created label = Label(root, image=white_img, borderwidth=0) label.grid(row=0, column=0) # button to close the app Button(root, text="Close", command=root.destroy).grid(row=1, column=0) root.focus_force() # this calls the test function to test without gpio # you don't need it with gpio # and you can remove drive_high and drive_low root.after(1000, drive_low) root.mainloop()
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
All humans together. We don't need politicians!