0

I've been working on adding a GPIO physical button function to a basic Tkinter GUI i've been developing.

(gui code is based on this example: http://pythonprogramming.net/change-show-new-frame-tkinter/)

Based on suggestions made here, I've added a gpio button function called "check_for_button_press", and it's using GPIO.add_event_detect and .after

I've been tweaking it, but I keep ending up with this error:

TypeError: check_for_button_press() takes exactly 1 argument (2 given)

There's obviously something basic that I'm missing, can anybody help me identify what it is? Thanks!

Here's the code with the new function commented:

import Tkinter as tk
import time
import RPi.GPIO as GPIO   
GPIO.setmode(GPIO.BCM)
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
GPIO.add_event_detect(5, GPIO.RISING)

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.attributes('-fullscreen', True)
        self.config(cursor="none")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=0)
        container.grid_columnconfigure(0, weight=0)

        self.frames = {}
        for F in (StartPage, PageOne):
            page_name = F.__name__
            frame = F(container, self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")


    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()

    def check_for_button_press(self):                #######check_for_button_press
        if GPIO.event_detected(5):                   #######GPIO
            self.show_frame(page_name)               #######
        self.after(10, self.check_for_button_press)  #######



class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        photonav1 = tk.PhotoImage(file="nav1.gif")
        photonav2 = tk.PhotoImage(file="nav2.gif")
        photonav3 = tk.PhotoImage(file="nav3.gif")
        photonav4 = tk.PhotoImage(file="nav4.gif")
        photonav5 = tk.PhotoImage(file="nav5.gif")
        photonav6 = tk.PhotoImage(file="nav6.gif")
        photosub1 = tk.PhotoImage(file="navmain1.gif")


        buttonnav1 = tk.Button(self, image=photonav1, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0,
                            command=lambda: controller.show_frame("PageOne"))

        buttonnav2 = tk.Button(self, image=photonav2, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageTwo"))

        buttonnav3 = tk.Button(self, image=photonav3, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageThree"))

        buttonnav4 = tk.Button(self, image=photonav4, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageFour"))

        buttonnav5 = tk.Button(self, image=photonav5, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageFive"))

        buttonnav6 = tk.Button(self, image=photonav6, width=158, height=38,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageSix"))

        buttonsub1 = tk.Button(self, image=photosub1, width=158, height=238,
    text="", bg='green', bd=0, highlightthickness=0, activebackground="green",
                            command=lambda: controller.show_frame("PageSix"))



        buttonsub1.pack(side=tk.RIGHT, fill=tk.Y, padx=0, pady=0)
        buttonsub1.image = photosub1        

        buttonnav1.pack()
        buttonnav1.image = photonav1

        buttonnav2.pack()
        buttonnav2.image = photonav2

        buttonnav3.pack()
        buttonnav3.image = photonav3

        buttonnav4.pack()
        buttonnav4.image = photonav4

        buttonnav5.pack()
        buttonnav5.image = photonav5

        buttonnav6.pack()
        buttonnav6.image = photonav6        


class PageOne(tk.Frame):

# ....
# ...
# ...   truncated
# ..
# .



if __name__ == "__main__":
    app = SampleApp()
    app.after(0, app.check_for_button_press, app)
    app.mainloop()
naturesrat
  • 21
  • 1
  • 5
  • Won't `self.after(10, self.check_for_button_press)` within `def check_for_button_press(self):` create an infinite recursion? If your program raises an exception after 2 hours and 46 minutes, that's why (python's default recursion depth limit is 1000 and you seem to be waiting for 10 seconds every time the function runs so...) – jDo Apr 28 '16 at 22:16
  • Thanks, I will check that out. New to using the after method – naturesrat Apr 29 '16 at 13:48
  • I meant why are you doing it? Does it have to call itself? I don't know much about tkinter either but it seems strange. Have you tried removing `self.after(10, self.check_for_button_press)` ? Any change? – jDo Apr 29 '16 at 14:11

1 Answers1

1

Why are you calling check_for_button_press like this initially?

app.after(0, app.check_for_button_press, app)

You should just call

app.check_for_button_press()

and after inside check_for_button_press will handle continuously checking by using the after method no need to use after twice here.

Looking at the after method you can pass:

after(delay_ms, callback, *args)

So, you are indeed passing two arguments.

Pythonista
  • 11,377
  • 2
  • 31
  • 50