Search code examples
pythontkinterkey-bindings

binding two buttons to the same widget tkinter


Is it possible to bind two diff keys to the same widget and call a different function. I am getting error that dbase() missing positional argument event even though i have passed in event as an argument

UPDATE: So the actual error is when i bind 'Return' to an entry widget and then i try clicking the button, then i get the error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
TypeError: dbase() missing 1 required positional argument: 'event'

Code:

def search():
    log = Toplevel(root)
    log.title('Search Book')
    def dbase(event):
        .....
    def clicker(event):
        ....
    def key_pressed(event):
        ....

    entry1.bind_all('<Key>',key_pressed)    
    button1.bind('<Button-1>',clicker)
    entry1.bind('<Return>',dbase)

Solution

  • When you press the button, it will call the function dbase. But your function dbase need to pass an argument event, but at this time, it won't pass any arguments.That's why it will raise Exception(If you call the dbase by the .bind, it will pass a argument).To solve this issue, you need to bind a default argument for your event:

    import tkinter
    
    def dbase(event=None):
        print("you are passing")
    
    r = tkinter.Tk()
    b = tkinter.Button(r,command=dbase)
    r.bind_all("<Return>", dbase)
    b.pack()
    
    r.mainloop()
    

    Or if you don't need the argument,use lambda in the bind:

    import tkinter
    
    def dbase():
        print("you are passing")
    
    r = tkinter.Tk()
    b = tkinter.Button(r,command=dbase)
    r.bind_all("<Return>", lambda e: dbase())
    b.pack()
    
    r.mainloop()
    

    This could work when you press the button directly or press <Enter>.