Button object not callable in Tkinter
Question:
I am trying to create a calculator app using Tkinter in python.
However, when I am trying to input my text in entry box i am getting the following error.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:UsersOptimusanaconda3envsvirtual_enviournmentlibtkinter__init__.py", line 1892, in __call__
return self.func(*args)
File "C:UsersOptimusAppDataLocalTemp/ipykernel_2608/2120973008.py", line 18, in <lambda>
button_7=Button(root, text="7", padx=40,pady=20, command=lambda: button_click(7))
TypeError: 'Button' object is not callable
my Code for the app is:
from tkinter import *
root=Tk()
root.title("Simple Calculator")
e=Entry(root, width=35, borderwidth=5)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10 )
def button_click(number):
e.delete(0, END)
e.insert(0, number)
#Define buttons
button_1=Button(root, text="1", padx=40,pady=20, command=lambda: button_click(1))
button_2=Button(root, text="2", padx=40,pady=20, command=lambda: button_click(2))
button_3=Button(root, text="3", padx=40,pady=20, command=lambda: button_click(3))
button_4=Button(root, text="4", padx=40,pady=20, command=lambda: button_click(4))
button_5=Button(root, text="5", padx=40,pady=20, command=lambda: button_click(5))
button_6=Button(root, text="6", padx=40,pady=20, command=lambda: button_click(6))
button_7=Button(root, text="7", padx=40,pady=20, command=lambda: button_click(7))
button_8=Button(root, text="8", padx=40,pady=20, command=lambda: button_click(8))
button_9=Button(root, text="9", padx=40,pady=20, command=lambda: button_click(9))
button_0=Button(root, text="0", padx=40,pady=20, command=lambda: button_click(0))
button_click=Button(root, text="+", padx=40,pady=20, command=lambda: button_click())
button_equals=Button(root, text="=", padx=120,pady=20, command=lambda: button_click())
button_clear=Button(root, text="Clear", padx=30,pady=20, command=lambda: button_click())
# Put the bottons
button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)
button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)
button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)
button_0.grid(row=4, column=0)
button_click.grid(row=4, column=1)
button_equals.grid(row=6, column=0, columnspan=3)
button_clear.grid(row=4, column=2)
root.mainloop()
Text is not getting entered in entry box.
Answers:
It seems to be because of this line:
button_click=Button(root, text="+", padx=40,pady=20, command=lambda: button_click())
Where you redefine button_click
as a Button
.
You have a function button_click
whereas you also have a button with the same name. Hence when you are passing a function in the command, the button calls by that name but by that time the button_click
is just a Button
that isn’t callable.
Rename the function to Click_Button
or rename the button in case the function does not have the same name as anything else it will work
I found a workaround for this problem, however, it makes the code a bit complex if there are greater number of buttons.
There is code for it:
from tkinter import *
from functools import partial
root=Tk()
root.title("Simple Calculator")
e=Entry(root, width=35, borderwidth=5)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10 )
def button_click(number):
e.delete(0, END)
e.insert(0, number)
action_with_arg1 = partial(button_click, 1)
action_with_arg2 = partial(button_click, 2)
action_with_arg3 = partial(button_click, 3)
action_with_arg4 = partial(button_click, 4)
action_with_arg5 = partial(button_click, 5)
action_with_arg6 = partial(button_click, 6)
action_with_arg7 = partial(button_click, 7)
action_with_arg8 = partial(button_click, 8)
action_with_arg9 = partial(button_click, 9)
action_with_arg0 = partial(button_click, 0)
#Define buttons
button_1=Button(root, text="1", padx=40,pady=20, command=action_with_arg1)
button_2=Button(root, text="2", padx=40,pady=20, command=action_with_arg2)
button_3=Button(root, text="3", padx=40,pady=20, command=action_with_arg3)
button_4=Button(root, text="4", padx=40,pady=20, command=action_with_arg4)
button_5=Button(root, text="5", padx=40,pady=20, command=action_with_arg5)
button_6=Button(root, text="6", padx=40,pady=20, command=action_with_arg6)
button_7=Button(root, text="7", padx=40,pady=20, command=action_with_arg7)
button_8=Button(root, text="8", padx=40,pady=20, command=action_with_arg8)
button_9=Button(root, text="9", padx=40,pady=20, command=action_with_arg9)
button_0=Button(root, text="0", padx=40,pady=20, command=action_with_arg0)
button_click=Button(root, text="+", padx=40,pady=20, command=button_click())
button_equals=Button(root, text="=", padx=120,pady=20, command=button_click())
button_clear=Button(root, text="Clear", padx=30,pady=20, command=button_click())
# Put the bottons
button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)
button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)
button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)
button_0.grid(row=4, column=0)
button_click.grid(row=4, column=1)
button_equals.grid(row=6, column=0, columnspan=3)
button_clear.grid(row=4, column=2)
root.mainloop()
I am trying to create a calculator app using Tkinter in python.
However, when I am trying to input my text in entry box i am getting the following error.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:UsersOptimusanaconda3envsvirtual_enviournmentlibtkinter__init__.py", line 1892, in __call__
return self.func(*args)
File "C:UsersOptimusAppDataLocalTemp/ipykernel_2608/2120973008.py", line 18, in <lambda>
button_7=Button(root, text="7", padx=40,pady=20, command=lambda: button_click(7))
TypeError: 'Button' object is not callable
my Code for the app is:
from tkinter import *
root=Tk()
root.title("Simple Calculator")
e=Entry(root, width=35, borderwidth=5)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10 )
def button_click(number):
e.delete(0, END)
e.insert(0, number)
#Define buttons
button_1=Button(root, text="1", padx=40,pady=20, command=lambda: button_click(1))
button_2=Button(root, text="2", padx=40,pady=20, command=lambda: button_click(2))
button_3=Button(root, text="3", padx=40,pady=20, command=lambda: button_click(3))
button_4=Button(root, text="4", padx=40,pady=20, command=lambda: button_click(4))
button_5=Button(root, text="5", padx=40,pady=20, command=lambda: button_click(5))
button_6=Button(root, text="6", padx=40,pady=20, command=lambda: button_click(6))
button_7=Button(root, text="7", padx=40,pady=20, command=lambda: button_click(7))
button_8=Button(root, text="8", padx=40,pady=20, command=lambda: button_click(8))
button_9=Button(root, text="9", padx=40,pady=20, command=lambda: button_click(9))
button_0=Button(root, text="0", padx=40,pady=20, command=lambda: button_click(0))
button_click=Button(root, text="+", padx=40,pady=20, command=lambda: button_click())
button_equals=Button(root, text="=", padx=120,pady=20, command=lambda: button_click())
button_clear=Button(root, text="Clear", padx=30,pady=20, command=lambda: button_click())
# Put the bottons
button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)
button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)
button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)
button_0.grid(row=4, column=0)
button_click.grid(row=4, column=1)
button_equals.grid(row=6, column=0, columnspan=3)
button_clear.grid(row=4, column=2)
root.mainloop()
Text is not getting entered in entry box.
It seems to be because of this line:
button_click=Button(root, text="+", padx=40,pady=20, command=lambda: button_click())
Where you redefine button_click
as a Button
.
You have a function button_click
whereas you also have a button with the same name. Hence when you are passing a function in the command, the button calls by that name but by that time the button_click
is just a Button
that isn’t callable.
Rename the function to Click_Button
or rename the button in case the function does not have the same name as anything else it will work
I found a workaround for this problem, however, it makes the code a bit complex if there are greater number of buttons.
There is code for it:
from tkinter import *
from functools import partial
root=Tk()
root.title("Simple Calculator")
e=Entry(root, width=35, borderwidth=5)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10 )
def button_click(number):
e.delete(0, END)
e.insert(0, number)
action_with_arg1 = partial(button_click, 1)
action_with_arg2 = partial(button_click, 2)
action_with_arg3 = partial(button_click, 3)
action_with_arg4 = partial(button_click, 4)
action_with_arg5 = partial(button_click, 5)
action_with_arg6 = partial(button_click, 6)
action_with_arg7 = partial(button_click, 7)
action_with_arg8 = partial(button_click, 8)
action_with_arg9 = partial(button_click, 9)
action_with_arg0 = partial(button_click, 0)
#Define buttons
button_1=Button(root, text="1", padx=40,pady=20, command=action_with_arg1)
button_2=Button(root, text="2", padx=40,pady=20, command=action_with_arg2)
button_3=Button(root, text="3", padx=40,pady=20, command=action_with_arg3)
button_4=Button(root, text="4", padx=40,pady=20, command=action_with_arg4)
button_5=Button(root, text="5", padx=40,pady=20, command=action_with_arg5)
button_6=Button(root, text="6", padx=40,pady=20, command=action_with_arg6)
button_7=Button(root, text="7", padx=40,pady=20, command=action_with_arg7)
button_8=Button(root, text="8", padx=40,pady=20, command=action_with_arg8)
button_9=Button(root, text="9", padx=40,pady=20, command=action_with_arg9)
button_0=Button(root, text="0", padx=40,pady=20, command=action_with_arg0)
button_click=Button(root, text="+", padx=40,pady=20, command=button_click())
button_equals=Button(root, text="=", padx=120,pady=20, command=button_click())
button_clear=Button(root, text="Clear", padx=30,pady=20, command=button_click())
# Put the bottons
button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)
button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)
button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)
button_0.grid(row=4, column=0)
button_click.grid(row=4, column=1)
button_equals.grid(row=6, column=0, columnspan=3)
button_clear.grid(row=4, column=2)
root.mainloop()