Search code examples
pythontkintercallbackargumentstkinter-entry

Tkinter/Python: Struggling to pass a argument through Entry.bind() method


I am running a simple piece of code that creates a little tk inter form/window that asks the user to enter the client's contact number, which I plan to use later to search for the clients details on a data base (besides the point)

I have used the .bind() method to trace when the user hits enter to accept the number input, but for the love of me, I can not seem to pass the argument to the callback fuction.

My code is below: can anyone tell what I may be doing wrong (this current code if the latest version of many after I have tried various fix attempts)

import tkinter as tk

def ClientNumberRequest():

   def SearchForClient(event, fun_client_num):
       search_numb = fun_client_num.get()
       # Do some stuff with the search number
    
   client_num_window = tk.Tk()
   form_label = tk.Label(client_num_window, text="Please enter the client's 
                         contact number")
   form_label.grid(row=0, column=0)
   client_num = tk.StringVar()
   form_entry = tk.Entry(client_num_window, textvariable=client_num)
   form_entry.grid(row=1, column=0)
   form_entry.focus_set()
   form_entry.bind("<Return>", lambda event, client_num: 
                  SearchForClient(event, client_num))

The error I get is below ONLY after I hit enter/return when running the programme

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\27826\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1884, in __call__

    return self.func(*args)
TypeError: <lambda>() missing 1 required positional argument: 'client_num'

Solution

  • The function called via the event must accept a single positional parameter, which will be passed an event object. If you want it to accept other arguments, they must be keyword arguments.

    You need to redefine your lambda to look like this:

    form_entry.bind("<Return>", lambda event, client_num=client_num: 
                   SearchForClient(event, client_num))
    

    However, if you're only using that parameter so that you can get the value, you don't need it since the event object has a reference to the widget and the widget has a get method:

    def SearchForClient(event):
       search_numb = event.widget.get()
    
    form_entry.bind("<Return>", SearchForClient)