How to build a calculator using python Tkinter

How to build a calculator using python Tkinter

One of the amazing projects any beginner will like to do is a calculator. Here I will be showing you how to design a calculator using Tkinter so let us get started.

Firstly we need to import some necessary libraries.

Importing the necessary library

firstly we need to import an important library that we are going to use in this project and that is Tkinter. so we will write the following codes.

from tkinter import *
from tkinter import messagebox

setting the window

Now I need to set the window and do the configuration, Here I will set the width to 36 and the background to pink with the following codes.

from tkinter import *
from tkinter import messagebox
window=Tk()
window.config(width=36,bg='pink')

creating the screen of the calculator

Here we will create a frame for screen part on the window using Frame() function. we will create the screen using Entry() function. we will also add font family and size including backgraound(bg) and fontground color(fg). you can change it to your own preferable colour. so let's add the following codes Codes

from tkinter import *
from tkinter import messagebox
window=Tk()
window.config(width=36,bg='pink')
screenPart=Frame(window)
screen=Entry(screenPart,font=("Algeria", 26, "bold"),
               bg='black',fg='white')
#adding screen box
screen.grid(column=0,row=0,padx=4)
screenPart.grid(row=0,column=0,pady=5)

Note: gird() function is used to specify the placement of the element created. here we mean the screen should be placed in the first column and first row. same for the screenPart. padx and pady give padding to the horizontal and vertical respectively.

Creating all the top sections of buttons.

Just like we did for the screen part, here we will create many buttons for our calculator. To create a button we will be using the BUtton() function. this function takes some parameters but we will be making use of the following parameter in our codes

  1. frame name to which the element(button) should be placed in this project we will use top
  2. text: this specifies the text written on the element(button). whatever assigned to this parameter will be displayed on the button.
  3. font: we already discuss this.
  4. bg: to specify the background color of the button or element
  5. command: this is the function to be executed whenever the button is clicked. we shall write codes for the function later and assign the function to the command.

Now we can add the following codes. codes

top=Frame(window)
top.config(bg='black',width=28)

one=Button(top,text="1",font=("Comic Sans MS", 20, "bold"),
           bg="green")
two=Button(top,text="2",font=("Comic Sans MS", 20, "bold"),
           bg="green")
three=Button(top,text="3",font=("Comic Sans MS",20, "bold"),
          bg="green")
ace=Button(top,text="AC",font=("Comic Sans MS", 20, "bold"),
           bg="red")
four=Button(top,text="4",font=("Comic Sans MS", 20, "bold"),
           bg="green")
five=Button(top,text="5",font=("Comic Sans MS", 20, "bold"),
           bg="green")

six=Button(top,text="6",font=("Comic Sans MS", 20, "bold"),
           bg="green")
delet=Button(top,text="←",font=("Comic Sans MS", 20,"bold"),
           bg="red")
seven=Button(top,text="7",font=("Comic Sans MS", 20, "bold"),
           bg="green")
eight=Button(top,text="8",font=("Comic Sans MS", 20, "bold"),
           bg="green")
nine=Button(top,text="9",font=("Comic Sans MS", 20, "bold"),
           bg="green")
lbrac=Button(top,text="(",font=("Comic Sans MS", 20, "bold"),
           bg="red")
zero=Button(top,text="0",font=("Comic Sans MS", 20, "bold"),
           bg="green")
dot=Button(top,text=".",font=("Comic Sans MS", 20, "bold"),
           bg="green")
multiply=Button(top,text="*",font=("Comic Sans MS", 20, "bold"),
           bg="green")

rbrac=Button(top,text=")",font=("Comic Sans MS", 20, "bold"),
           bg="red")

If you run the codes we have now it will brings out noting than the screen of the calculator. Yeah! that is because we are only creating the button element inside the frame(top) without placement.

Positioning the buttons inside frame and frame in to window to display it we need to place each of the button inside the frame(top) and place the frame(top) inside window by specifying the row and column using grid() function. so we will add the following codes

Codes>>


#____to position the button inside the frame.____
one.grid(row=0,column=0,padx=3)
#button in first row and first column of top frame
two.grid(row=0,column=1,padx=3)
# button in first row and second column of top frame 
three.grid(row=0,column=2,padx=3)
#button in first row and third column of top frame
ace.grid(row=0,column=3,padx=3)
#button in first row and fourth column of top frame
four.grid(row=1,column=0,padx=3)
#button in second row and first column of top frame
five.grid(row=1,column=1,padx=3)
#button in second row and second column of top frame
six.grid(row=1,column=2,padx=3)
#button in second row and third column of top frame
delet.grid(row=1,column=3,padx=3)
#button in second row and first column of top frame
seven.grid(row=2,column=0,padx=3)
#button in third row and first column of top frame
eight.grid(row=2,column=1,padx=3)
# button in third row and second column of top frame
nine.grid(row=2,column=2,padx=3)
#button in third row and third column of top frame
lbrac.grid(row=2,column=3,padx=3)
#button in third row and fourth column of top frame
zero.grid(row=3,column=0,padx=3)
#button in fourth row and first column of the top frame
dot.grid(row=3,column=1,padx=3)
# button in fourth row and second column of the top frame
multiply.grid(row=3,column=2,padx=3)
#button in fourth row and third columnn of the top frame
rbrac.grid(row=3,column=3,padx=3)
#button in fourth row and fourth column of the top frame

#place the top frame part to second row and first column of the window.
top.grid(row=1,column=0,padx=0)

Now if you run the codes you will see something like below Result

Adding more useful buttons I believe that is not bad for start, Now we get a screen and some buttons right?? let's add more button using another frame. add the following codes codes


end=Frame(window)#creating another frame
plus=Button(end,text="+",font=("Comic Sans MS",22 , "bold"),
          bg="red",command=lambda: digits('+'))
#creating plus button
divide=Button(end,text="/",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: digits('/'))
#creating divide button
minus=Button(end,text="-",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: digits('-'))
#creating minus button
power=Button(end,text="^",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: digits('^'))
#creating power button
equal=Button(end,text="=",font=("Comic Sans MS", 22, "bold"),
           bg="red")
#creating equal to button
descrip=Button(end,text="Desc",font=("Comic Sans MS", 22, "bold"),bg="red")
 #creating description button


#----placing the elements in to the end  frame.-------
divide.grid(row=0,column=0,padx=3)#button in first row and first column of the end frame
power.grid(row=0,column=1,padx=3)#button in first row and second column of the end frame
plus.grid(row=0,column=2,padx=3)#button in first row and third column of the end frame
minus.grid(row=1,column=0,padx=3)#button in second row and first column of the end frame
equal.grid(row=1,column=1,padx=3)#button in second row and second column of the end frame
descrip.grid(row=1,column=2,padx=3)#button in seond row and third column of the end frame

#placing the end frame in to the window
end.grid(row=2,column=0,padx=0)#place to third row of the window

I believe you should understand the codes it is just like the way we did the top frame. if you run the codes you should see something like the following.

Setting the width and height of each element

Now if you observed well, the button are not well arranged they are of different with and that make it look so bad. so, to modify that we will do the configuration. using config() function with the follwoing codes.

codes


#setting the width of each element
screen.config(width=19)

one.config(width=4,height=1)
two.config(width=4,height=1)
three.config(width=4,height=1)
ace.config(width=6,height=1)
four.config(width=4,height=1)
five.config(width=4,height=1)
six.config(width=4,height=1)
delet.config(width=6,height=1)
seven.config(width=4,height=1)
eight.config(width=4,height=1)
nine.config(width=4,height=1)
lbrac.config(width=6,height=1)
zero.config(width=4,height=1)
dot.config(width=4,height=1)
multiply.config(width=4,height=1)
rbrac.config(width=6)

power.config(width=6,height=1)
plus.config(width=6,height=1)
divide.config(width=6,height=1)
equal.config(width=6,height=1)
minus.config(width=6,height=1)
descrip.config(width=6,height=1)

Now run the codes and see the beautiful thing below

it is nice right?? Yeah! we are almost done, everything looks perfect now but our calculator is not working yet. so to make it work we need to create some functions that are going to do that for us.

Creating function to make the calculator work

Before the calculator could work as we expected we need to create some function which are going to do some certain task. The fuction are as follow

  1. appendScreen() function: this is a function we are going to create ourself it work is to add character to the screen, such that each button click will be display on the screen. Now let us write the function codes and call it on the buttons that need it. so we would add the following codes.

Code>>

def appendScreen(value):
    global screen # the element created using tkinter  
    screen_values=str(screen.get())
    new_screen_values = screen_values+(str(value))
    screen.delete(0,END)#delete the value on the screen
    screen.insert(1,new_screen_values)#insert new value to the screen.

Now as you can see the function above is going to take one parameter of which the parameter represent the value to be added to the screen when clicked.

Now we would add the function to some of the buttons like zero,one,two,three...nine. also plus, minus,times, divide,brackets and power. all these buttons hold values that needed to be displayed on the screen. so we need to adjust our code remember I already told you about Command. so we adjust our previous code like the following.

codes

top=Frame(window)
top.config(bg='black',width=28)

one=Button(top,text="1",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("1"))
two=Button(top,text="2",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("2"))
three=Button(top,text="3",font=("Comic Sans MS",20, "bold"),
          bg="green",command=lambda: appendScreen("3"))
ace=Button(top,text="AC",font=("Comic Sans MS", 20, "bold"),
           bg="red")
four=Button(top,text="4",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("4"))
five=Button(top,text="5",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("5"))

six=Button(top,text="6",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("6"))
delet=Button(top,text="←",font=("Comic Sans MS", 20,"bold"),
           bg="red")
seven=Button(top,text="7",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("7"))
eight=Button(top,text="8",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("8"))
nine=Button(top,text="9",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("9"))
lbrac=Button(top,text="(",font=("Comic Sans MS", 20, "bold"),
           bg="red",command=lambda: appendScreen("("))
zero=Button(top,text="0",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("0"))
dot=Button(top,text=".",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("."))
multiply=Button(top,text="*",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("*"))

rbrac=Button(top,text=")",font=("Comic Sans MS", 20, "bold"),
           bg="red",command=lambda: appendScreen(")"))

Now run the codes and click on the button did you see the difference?? Note: we add no command to delete and ace because they are not meant to display anything on the screen. the following show the image of working buttons.

Now there are more buttons that hold values to be display on the screen. they are divide,power, plus and minus. so we need to adjust end frame part too.

codes


end=Frame(window)#creating another frame
plus=Button(end,text="+",font=("Comic Sans MS",22 , "bold"),
          bg="red",command=lambda: appendScreen('+'))
#creating plus button
divide=Button(end,text="/",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('/'))
#creating divide button
minus=Button(end,text="-",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('-'))
#creating minus button
power=Button(end,text="^",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('^'))
#creating power button
equal=Button(end,text="=",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: calculate())
#creating equal to button
descrip=Button(end,text="Desc",font=("Comic Sans MS", 22, "bold"),
 bg="red",command=lambda: descrip())
 #creating description button

Now you can click each of the button to see that they display well.

Now that we were able the display some necessary character we should create a function that will do the calculation for us which is going to be call by equal to button.

  1. calculat() function: function to calcuculate the whole thing display on the screen. let's quickly write codes for the function.

codes

def calculate():
    global screen   
    screen_values=str(screen.get())
    #get the values on the screen and convert to string
    result = eval(screen_values.replace('^','**')) 
    #replace '^' by '**' and evaluate
    screen.delete(0,END)
    screen.insert(1,result)#display result on the screen.

Now let's call the function where we create equal to button and add command like the following.

Codes

equal=Button(end,text="=",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: calculate())
#creating equal to button

Now you can test it by clicking equal to. you will see that it works well. is that all?NO! we need a function that will delete the last character on the screen also the function that will delete all characters on the screen. so let's quickly write the function for both.

clear screen and deleting function

 def clear():
    global screen
    new_value=''

    screen.delete(0,END)
    screen.insert(1,new_value)

def delet():
    global screen
    screen_values=str(screen.get())
    new_values = screen_values[0:-1]#get value without the last characters
    screen.delete(0,END)
    screen.insert(1,new_values)

now we have to call the two function in delete and Ac button. so we will adjust the codes use to create the button. codes

delet=Button(top,text="←",font=("Comic Sans MS", 20,"bold"),
           bg="red",command=lambda: delet())
ace=Button(top,text="AC",font=("Comic Sans MS", 20, "bold"),
           bg="red",command=lambda: clear())

after adding that the whole codes will look like below


from tkinter import *
from tkinter import messagebox
window=Tk()
window.config(width=36,bg='pink')
screenPart=Frame(window)
screen=Entry(screenPart,font=("Algeria", 26, "bold"),
               bg='black',fg='white')
#adding screen box
screen.grid(column=0,row=0,padx=4)
#place the screen to first row and first column of the screenPart frame
screenPart.grid(row=0,column=0,pady=5)
#place the screenPart frame to first row and first column of the window

#creating the top and frame and elements in it
top=Frame(window)
top.config(bg='black',width=28)

one=Button(top,text="1",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("1"))
two=Button(top,text="2",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("2"))
three=Button(top,text="3",font=("Comic Sans MS",20, "bold"),
          bg="green",command=lambda: appendScreen("3"))
ace=Button(top,text="AC",font=("Comic Sans MS", 20, "bold"),
           bg="red")
four=Button(top,text="4",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("4"))
five=Button(top,text="5",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("5"))

six=Button(top,text="6",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("6"))
delet=Button(top,text="←",font=("Comic Sans MS", 20,"bold"),
           bg="red")
seven=Button(top,text="7",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("7"))
eight=Button(top,text="8",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("8"))
nine=Button(top,text="9",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("9"))
lbrac=Button(top,text="(",font=("Comic Sans MS", 20, "bold"),
           bg="red",command=lambda: appendScreen("("))
zero=Button(top,text="0",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("0"))
dot=Button(top,text=".",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("."))
multiply=Button(top,text="*",font=("Comic Sans MS", 20, "bold"),
           bg="green",command=lambda: appendScreen("*"))

rbrac=Button(top,text=")",font=("Comic Sans MS", 20, "bold"),
           bg="red",command=lambda: appendScreen(")"))

#------------------------------------------------
#____to position the button inside the frame.____
one.grid(row=0,column=0,padx=3)
#button in first row and first column of top frame
two.grid(row=0,column=1,padx=3)
# button in first row and second column of top frame 
three.grid(row=0,column=2,padx=3)
#button in first row and third column of top frame
ace.grid(row=0,column=3,padx=3)
#button in first row and fourth column of top frame
four.grid(row=1,column=0,padx=3)
#button in second row and first column of top frame
five.grid(row=1,column=1,padx=3)
#button in second row and second column of top frame
six.grid(row=1,column=2,padx=3)
#button in second row and third column of top frame
delet.grid(row=1,column=3,padx=3)
#button in second row and first column of top frame
seven.grid(row=2,column=0,padx=3)
#button in third row and first column of top frame
eight.grid(row=2,column=1,padx=3)
# button in third row and second column of top frame
nine.grid(row=2,column=2,padx=3)
#button in third row and third column of top frame
lbrac.grid(row=2,column=3,padx=3)
#button in third row and fourth column of top frame
zero.grid(row=3,column=0,padx=3)
#button in fourth row and first column of the top frame
dot.grid(row=3,column=1,padx=3)
# button in fourth row and second column of the top frame
multiply.grid(row=3,column=2,padx=3)
#button in fourth row and third columnn of the top frame
rbrac.grid(row=3,column=3,padx=3)
#button in fourth row and fourth column of the top frame
top.grid(row=1,column=0,padx=0)



end=Frame(window)#creating another frame
plus=Button(end,text="+",font=("Comic Sans MS",22 , "bold"),
          bg="red",command=lambda: appendScreen('+'))
#creating plus button
divide=Button(end,text="/",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('/'))
#creating divide button
minus=Button(end,text="-",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('-'))
#creating minus button
power=Button(end,text="^",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: appendScreen('^'))
#creating power button
equal=Button(end,text="=",font=("Comic Sans MS", 22, "bold"),
           bg="red",command=lambda: calculate())
#creating equal to button
descrip=Button(end,text="Desc",font=("Comic Sans MS", 22, "bold"),
 bg="red",command=lambda: descrip())
#creating description button

#placing the element in to the end  frame.
divide.grid(row=0,column=0,padx=3)#button in first row and fourth column
power.grid(row=0,column=1,padx=3)#button in first row and third column
plus.grid(row=0,column=2,padx=3)#button in first row and fourth column
minus.grid(row=1,column=0,padx=3)#button in first row and fourth column
equal.grid(row=1,column=1,padx=3)#button in first row and fourth column
descrip.grid(row=1,column=2,padx=3)#button in first row and fourth column

#placing the end frame in to the window
end.grid(row=2,column=0,padx=0)#place to third row of the window


#setting the width of each element
screen.config(width=19)
four.config(width=4,height=1)
three.config(width=4,height=1)
two.config(width=4,height=1)
one.config(width=4,height=1)
five.config(width=4,height=1)
six.config(width=4,height=1)
seven.config(width=4,height=1)
eight.config(width=4,height=1)
nine.config(width=4,height=1)
zero.config(width=4,height=1)

dot.config(width=4,height=1)
multiply.config(width=4,height=1)
ace.config(width=6,height=1)
lbrac.config(width=6,height=1)
rbrac.config(width=6)
delet.config(width=6,height=1)

power.config(width=6,height=1)
plus.config(width=6,height=1)
divide.config(width=6,height=1)
equal.config(width=6,height=1)
minus.config(width=6,height=1)
descrip.config(width=6,height=1)

def appendScreen(value):
    global screen # the element created using tkinter  
    screen_values=str(screen.get())
    new_screen_values = screen_values+(str(value))
    screen.delete(0,END)#delete the value on the screen
    screen.insert(1,new_screen_values)#insert new value to the screen.

def calculate():
    global screen   
    screen_values=str(screen.get())
    #get the values on the screen and convert to string
    result = eval(screen_values.replace('^','**')) 
    #replace '^' by '**' and evaluate
    screen.delete(0,END)
    screen.insert(1,result)#display result on the screen.

Now run the code again and click all the buttons does it work well?? yeah! it is as easy as that. I hope you enjoy it? consider subscribing so that you don't miss any of my next articles. you can also chat me up on Whatsapp if you have any questions. don t forget to follow me on Twitter.