Related
So I am new here and this may be very basic but I need your help. I am new to tkinter and was building a calculator as my first project. I wanted the functions of the calculator in a separate file, but when I import them in the main file they don't seem to work. I think it's a problem with global variables but don't know how to fix it.
Here's the error and the code snippets:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\AKHIL\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "c:\Users\AKHIL\OneDrive\Documents\GitHub\CS-project\calc.py", line 83, in <lambda>
button_6 = Button(calc, text="6", padx=40, pady=20, command=lambda: button_click(6))
File "c:\Users\AKHIL\OneDrive\Documents\GitHub\CS-project\function.py", line 8, in button_click
current = display.get()
NameError: name 'display' is not defined
this is calc.py
from tkinter import *
from function import *
calc = Tk()
calc.title("Calculator")
calc.iconbitmap("calc.ico")
button_1 = Button(calc, text="1", padx=40, pady=20, command=lambda: button_click(1))
button_2 = Button(calc, text="2", padx=40, pady=20, command=lambda: button_click(2))
button_3 = Button(calc, text="3", padx=40, pady=20, command=lambda: button_click(3))
button_4 = Button(calc, text="4", padx=40, pady=20, command=lambda: button_click(4))
button_5 = Button(calc, text="5", padx=40, pady=20, command=lambda: button_click(5))
button_6 = Button(calc, text="6", padx=40, pady=20, command=lambda: button_click(6))
button_7 = Button(calc, text="7", padx=40, pady=20, command=lambda: button_click(7))
button_8 = Button(calc, text="8", padx=40, pady=20, command=lambda: button_click(8))
button_9 = Button(calc, text="9", padx=40, pady=20, command=lambda: button_click(9))
button_0 = Button(calc, text="0", padx=40, pady=20, command=lambda: button_click(0))
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)
And this is function.py
from tkinter import *
def button_click(number):
global display
current = display.get()
display.delete(0, END)
display.insert(0, str(current) + str(number))
This question already has an answer here:
Button object not callable in the tkinter code
(1 answer)
Closed 3 months ago.
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:\Users\Optimus\anaconda3\envs\virtual_enviournment\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\Optimus\AppData\Local\Temp/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.
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
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.
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()
import tkinter as tk
root = tk.Tk()
root.title("Simple Calculator")
e= tk.Entry(root,width=35, borderwidth=5)
e.grid(row=0,column=0, columnspan=3, padx=10, pady=10)
#define button_click
def button_click(number):
e.delete(0,END)
e.insert(0,number)
#Define Buttons
button_1 = tk.Button(root, text="1", padx=40, pady=20, command= lambda: button_click(1))
button_2 = tk.Button(root, text="2", padx=40, pady=20, command= lambda: button_click(2))
button_3 = tk.Button(root, text="3", padx=40, pady=20, command=lambda: button_click(3))
button_4 = tk.Button(root, text="4", padx=40, pady=20, command=lambda: button_click(4))
button_5 = tk.Button(root, text="5", padx=40, pady=20, command=lambda: button_click(5))
button_6 = tk.Button(root, text="6", padx=40, pady=20, command=lambda: button_click(6))
button_7 = tk.Button(root, text="7", padx=40, pady=20, command=lambda: button_click(7))
button_8 = tk.Button(root, text="8", padx=40, pady=20, command=lambda: button_click(8))
button_9 = tk.Button(root, text="9", padx=40, pady=20, command=lambda: button_click(9))
button_0 = tk.Button(root, text="0", padx=40, pady=20, command=lambda: button_click(0))
button_add = tk.Button(root, text="+", padx=39, pady=20, command=lambda: button_click())
button_equal = tk.Button(root, text="=", padx=91, pady=20, command=lambda: button_click())
button_clear = tk.Button(root, text="Clear", padx=79, pady=20, command=lambda: button_click())
# Put the buttons on the screen
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_clear.grid(row=4, column=1, columnspan=2)
button_add.grid(row=5, column=0)
button_equal.grid(row=5, column=1, columnspan=2)
root.mainloop()
Simply
def button_click(number):
e.delete(0, tk.END) # tk.END instead of END
e.insert(0,number)
This is because you've used
import tkinter as tk
which means that all functions that are inside tkinter are stored in the tk variable.
I'm trying to create a roulette table (which I have done as a GUI). Now, when I press the button for the outcome it shows the number in my top box, but I'm struggling to find a way to collect the results in a list, so I can then later pull data from the list.
For example, I want a list of past results so that I could show that's it's been 4 spins without landing on a odd number or it's been 3 spins since it's been red, or on average it lands in the 1st 12 every 3 spins.
I have tried numerous ways of collecting results from the buttons clicked but nothing works.
from tkinter import*
# Roulette GUI
root = Tk()
root.title("Roulette")
e = Entry(root, width=200, borderwidth=5)
e.grid(row=0, column=0, columnspan=13, padx=10, pady=10)
def button_click(number):
e.delete(0, END)
e.insert(0, number)
print(number)
# define buttons
button_0 = Button(root, text="0", padx=40, pady=84, bg='green', command=lambda: button_click(0))
button_1 = Button(root, text="1", padx=40, pady=20, bg='red', command=lambda: button_click(1))
button_2 = Button(root, text="2", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(2))
button_3 = Button(root, text="3", padx=40, pady=20, bg='red', command=lambda: button_click(3))
button_4 = Button(root, text="4", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(4))
button_5 = Button(root, text="5", padx=40, pady=20, bg='red', command=lambda: button_click(5))
button_6 = Button(root, text="6", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(6))
button_7 = Button(root, text="7", padx=40, pady=20, bg='red', command=lambda: button_click(7))
button_8 = Button(root, text="8", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(8))
button_9 = Button(root, text="9", padx=40, pady=20, bg='red', command=lambda: button_click(9))
button_10 = Button(root, text="10", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(10))
button_11 = Button(root, text="11", padx=40, pady=20, bg='red', command=lambda: button_click(11))
button_12 = Button(root, text="12", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(12))
button_13 = Button(root, text="13", padx=40, pady=20, bg='red', command=lambda: button_click(13))
button_14 = Button(root, text="14", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(14))
button_15 = Button(root, text="15", padx=40, pady=20, bg='red', command=lambda: button_click(15))
button_16 = Button(root, text="16", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(16))
button_17 = Button(root, text="17", padx=40, pady=20, bg='red', command=lambda: button_click(17))
button_18 = Button(root, text="18", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(18))
button_19 = Button(root, text="19", padx=40, pady=20, bg='red', command=lambda: button_click(19))
button_20 = Button(root, text="20", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(20))
button_21 = Button(root, text="21", padx=40, pady=20, bg='red', command=lambda: button_click(21))
button_22 = Button(root, text="22", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(22))
button_23 = Button(root, text="23", padx=40, pady=20, bg='red', command=lambda: button_click(23))
button_24 = Button(root, text="24", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(24))
button_25 = Button(root, text="25", padx=40, pady=20, bg='red', command=lambda: button_click(25))
button_26 = Button(root, text="26", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(26))
button_27 = Button(root, text="27", padx=40, pady=20, bg='red', command=lambda: button_click(27))
button_28 = Button(root, text="28", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(28))
button_29 = Button(root, text="29", padx=40, pady=20, bg='red', command=lambda: button_click(29))
button_30 = Button(root, text="30", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(30))
button_31 = Button(root, text="31", padx=40, pady=20, bg='red', command=lambda: button_click(31))
button_32 = Button(root, text="32", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(32))
button_33 = Button(root, text="33", padx=40, pady=20, bg='red', command=lambda: button_click(33))
button_34 = Button(root, text="34", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(34))
button_35 = Button(root, text="35", padx=40, pady=20, bg='red', command=lambda: button_click(35))
button_36 = Button(root, text="36", padx=40, pady=20, bg='black', fg='white', command=lambda: button_click(36))
button_exit = Button(root, text="Exit", padx=60, pady=20, command=root.quit)
# put buttons on the screen
button_0.grid(row=1, rowspan=3, column=0)
button_1.grid(row=3, column=1)
button_2.grid(row=2, column=1)
button_3.grid(row=1, column=1)
button_4.grid(row=3, column=2)
button_5.grid(row=2, column=2)
button_6.grid(row=1, column=2)
button_7.grid(row=3, column=3)
button_8.grid(row=2, column=3)
button_9.grid(row=1, column=3)
button_10.grid(row=3, column=4)
button_11.grid(row=2, column=4)
button_12.grid(row=1, column=4)
button_13.grid(row=3, column=5)
button_14.grid(row=2, column=5)
button_15.grid(row=1, column=5)
button_16.grid(row=3, column=6)
button_17.grid(row=2, column=6)
button_18.grid(row=1, column=6)
button_19.grid(row=3, column=7)
button_20.grid(row=2, column=7)
button_21.grid(row=1, column=7)
button_22.grid(row=3, column=8)
button_23.grid(row=2, column=8)
button_24.grid(row=1, column=8)
button_25.grid(row=3, column=9)
button_26.grid(row=2, column=9)
button_27.grid(row=1, column=9)
button_28.grid(row=3, column=10)
button_29.grid(row=2, column=10)
button_30.grid(row=1, column=10)
button_31.grid(row=3, column=11)
button_32.grid(row=2, column=11)
button_33.grid(row=1, column=11)
button_34.grid(row=3, column=12)
button_35.grid(row=2, column=12)
button_36.grid(row=1, column=12)
button_exit.grid(row=4, column=11, columnspan=2)
root.mainloop()
if you are trying to see percentage of pressing red and black buttons, this code print it on your console
from tkinter import*
root = Tk()
root.title("Roulette")
e = Entry(root, width=200, borderwidth=5)
e.grid(row=0, column=0, columnspan=13, padx=10, pady=10)
results = []
def button_click(number):
e.delete(0, END)
e.insert(0, number)
results.append(number)
#loop through results
count = 0
for i in range(len(results)):
if results[i]%2 == 0:
count += 1
print("Number is",number)
red_percentage = count/len(results)*100
print("Black", 100-red_percentage)
print("Red", red_percentage)
print("------------------------------------")
# define buttons
button = Button(root, text="0", padx=40, pady=84, bg='green', command=lambda: button_click(0))
button.grid(row=1, rowspan=3, column=0)
for i in range(0,36):
if i%2 == 0:
button = Button(root, text=str(i+1), padx=40, pady=20, bg='black', fg='white', command=lambda i=i:button_click(i+1))
else:
button = Button(root, text=str(i+1), padx=40, pady=20, bg='red', command=lambda i=i: button_click(i+1))
button.grid(row=3 - i%3, column=int(i/3) + 1)
button = Button(root, text="Exit", padx=60, pady=20, command=root.quit)
button.grid(row=4, column=11, columnspan=2)
root.mainloop()
So, I started the tkinter tutorial from freecodecamp.org and I'm at the point of making a calculator. I'm following the tutorial to the letter while also experimenting a bit on my own. Here arose my problem, in the video the calculator outputs the sum of the 2 last numbers and that, if you press "number + number =" so no matter how many numbers do you press and the + after them, only the last two will be added. What I want to do is that whenever I press the + button, the sum is stored in the global variable but I'm having trouble doing that.
from tkinter import *
root = Tk()
root.title("Simple calculator")
e = Entry(root, width=35, borderwidth=3)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10)
# button functions
def button_click(number):
# e.delete(0, END)
current = e.get()
e.delete(0, END)
e.insert(0, str(current) + str(number))
def button_clear():
e.delete(0, END)
def button_add():
temp = 0 + int(e.get())
global v_keeper
v_keeper = int(temp)
e.delete(0,END)
def button_equal():
temp = int(e.get())
e.delete(0,END)
e.insert(0,v_keeper + temp)
#button gui
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_add = Button(root, text="+", padx=39, pady=20, command=button_add)
button_equal = Button(root, text="=", padx=91, pady=20, command=button_equal)
button_clear = Button(root, text="Clear", padx=79, pady=20, command=button_clear)
# put buttons on screen
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_clear.grid(row=4, column=1, columnspan=2)
button_add.grid(row=5, column=0)
button_equal.grid(row=5, column=1, columnspan=2)
# myButton = Button(root, text="Enter your name", command=myClick)
root.mainloop()
Disclaimer: You should avoid global variables whenever possible. They tend to lead to unmaintainable, unstructured code.
Here is the solution path for your globals:
First: Define the global variable v_keep at the beginning of your script and initialize it to 0.
Second: In button_add you were assigning the wrong value to it. You want to store the current total sum there.
Third: You need to update v_keeper as well in button_clear and button_equal.
This is the part of your code I changed, in order to get the desired result:
v_keeper = 0
# button functions
def button_click(number):
# e.delete(0, END)
current = e.get()
e.delete(0, END)
e.insert(0, str(current) + str(number))
def button_clear():
global v_keeper
v_keeper = 0
e.delete(0, END)
def button_add():
global v_keeper
v_keeper = v_keeper + int(e.get())
e.delete(0, END)
Updating button_equal is left as an exercise to the reader :)