Skip to content Skip to sidebar Skip to footer

I Want To Toggle A Real Pushbutton And Display It On Tkinter Gui

I want to toggle a pushbutton and show its changes on a label using tkinter. If I press the button it shows 'on' on the label and when I press again it shows 'off' on the label So

Solution 1:

Your problem is recognizing button down and button up events. Your OS mouse driver does this for your mouse buttons. If your GPIO module does not do this for you, you will have to detect these events by comparing the current state to the previous state. (I am ignoring here any possible need to 'de-bounce' the button.) You are sort of trying to do this with the time.sleep(.5) calls, but do not use time.sleep in gui code.

Your driver should be self-contained and independent of any tk widgets other than the root needed for .after. For multiple buttons, you will need your own GPIOButton class. Your code that works is a starting point. Tkinter allows you to tie a command to button-up events. Your class init should similarly take up and or down event commands (callbacks).

Here is something untested that might get you started.

classGPIOButton:
    def__init__(self, master, buttons, command_down=None, command_up=None):
        self.master = master
        self.buttons = buttons
        self.command_down = command_down
        self.command_up = command_up
        GPIO.setmode(GPIO.BOARD)
        for button in buttons:
            GPIO.setup(button, GPIO.IN)
        self.state = [GPIO.HIGH] * len(buttons)  # best initial value?
        self.check_buttons()  # or call this elsewheredefcheck_buttons(self):
        for i, button inenumerate(self.buttons):
            oldstate = self.state[i]
            newstate = GPIO.input(button)
            if oldstate != newstate:
                self.state[i] = newstate
                command = (self.command_down if newstate==GPIO.LOW
                           else self.command_up)
                command(button)
        self.master.after(10, self.check_button)

Solution 2:

Let me preface my answer with a disclaimer—I don't have a Raspberry Pi, so couldn't verify this works with the real thing. For testing I used a proxy class that simulates random button pressing. You may have to adjust the DELAY value depending on how fast the GPIO interface works.

However, I have put commented-out code in near the top showing what I think you would need to use based on of doing so in your code.

try:
    import Tkinter as tk
    import tkFont
except ImportError:  # Python 3import tkinter as tk
    import tkinter.font as tkFont

#import RPi.GPIO as GPIO##GPIO.setmode(GPIO.BOARD)##class GPIOButton(object):#    """ Encapsulates GPIO button interface. """#    def __init__(self, pin):#        self.pin = pin#        self.status = 0#        GPIO.setup(pin, GPIO.IN)##    def update_status(self):#        self.status = GPIO.input(pin) == GPIO.LOW### Proxy class since I don't have a Rasperry Pi. ###import random

classGPIOButton(object):
    def__init__(self, pin):
        self.pin = pin
        self.status = 0defupdate_status(self):
        ifnot random.randint(0, 99) % 20:  # occassionally toggle status
            self.status = not self.status

classApp(tk.Frame):
    STRIDE = 8
    DELAY = 100# delay in millsecs between button status updatesdef__init__(self, gpio_buttons, master=None):
        tk.Frame.__init__(self, master)
        self.grid()
        self.gpio_buttons = gpio_buttons
        self.create_widgets()
        self.after(self.DELAY, self.update_buttons, self.DELAY)  # start updatesdefcreate_widgets(self):
        self.btn_font = tkFont.Font(family="Helvetica", size=12, weight='bold')
        self.gui_buttons = []
        for i, button inenumerate(self.gpio_buttons):
            is_pressed = tk.BooleanVar()
            is_pressed.set(False)
            radiobutton = tk.Radiobutton(self,
                                         text=format(i+1, '02d'),
                                         font=self.btn_font,
                                         value=True,
                                         variable=is_pressed,
                                         relief=tk.RIDGE)
            row, col = divmod(i, self.STRIDE)
            radiobutton.grid(column=col, row=row)
            self.gui_buttons.append(is_pressed)

    defupdate_buttons(self, delay):
        for i, gpio_button inenumerate(self.gpio_buttons):
            previous_status = gpio_button.status
            gpio_button.update_status()
            if gpio_button.status != previous_status:
                self.gui_buttons[i].set(gpio_button.status)

        self.after(delay, self.update_buttons, delay)  # rinse and repeat


gpio_buttons = [GPIOButton(pin) for pin inrange(16)]
app = App(gpio_buttons)
app.master.title('Rasberry Pi Buttons')
app.mainloop()

Here's what the simulation looks like running on my Windows computer:

screenshot of display showing the status of all sixteen buttons

Post a Comment for "I Want To Toggle A Real Pushbutton And Display It On Tkinter Gui"