DEV Community

Cover image for Calculator with GUI Using Python Tkinter.
Ebikara Spiff
Ebikara Spiff

Posted on • Edited on

Calculator with GUI Using Python Tkinter.

Introduction

In today's fast-paced world, where we often need to do quick calculations, having a good calculator is important. Whether you're a student doing homework or a professional managing finances, having a calculator handy can be super useful. But have you ever thought about making your own?

If you've ever wanted to learn how to use Python or if you already know a bit and want to try something new, then you're in the right place! In this article, we'll show you step-by-step how to make your very own calculator using Python's Tkinter library, a renowned Python library for creating graphical user interfaces. Tkinter stands out for its simplicity, versatility, and widespread use in the Python community. It doesn't matter if you're a total beginner or an experienced coder looking for a fun project, we'll guide you through everything you need to know.

Get ready to discover the world of coding as we show you how to create your calculator from scratch. It's going to be a fun and rewarding journey, and you'll be amazed at what you can accomplish!

SETTING UP THE PROJECT ENVIRONMENT

When working in Visual Studio Code (VS Code), start by creating a new Python file for your project. It's helpful to have separate files for different parts of your project.

Create a new Python application:

To do this, you can start by opening your VS Code and creating a new folder:

Step 1

Image of a new folder in VS code

Step 2

You select the folder:

Image of newly created vs code folder

Step 3

Head over to the newly created folder and create a new file called app.py.

creating a new file called app.py.

Install the necessary libraries.

We will create this calculator with Python using Tkinter.

First, we import the Tkinter library and components, modules that we need:



import tkinter as tk

LARGE_FONT_STYLE = ("Arial", 40,"bold")
SMALL_FONT_STYLE = ("Arial", 16)
DIGITS_FONT_STYLE = ("Arial", 24,"bold")
DEFAULT_FONT_STYLE = ( "Arial",20)

OFF_WHITE = "#F8FAFF"
WHITE = #FFFFFF#
LIGHT_BLUE ="#CCEDFF"
LIGHT_GRAY  =  "#F5F5F5"
LABEL_COLOR =  "#25265E"



Enter fullscreen mode Exit fullscreen mode

Building the Calculator

We will create a class Calculator that will contain all the components and functionality of our calculator:

step 1



class calculator:


Enter fullscreen mode Exit fullscreen mode

step 2

We will define an init method for the calculator class:



def__init__(self):


Enter fullscreen mode Exit fullscreen mode

step 3

Next, we will create the main window of our calculator:



self.window=tk.Tk()


Enter fullscreen mode Exit fullscreen mode

step 4

We will specify the width and height of this window:



self.window = geometry("375x667")


Enter fullscreen mode Exit fullscreen mode

step 5

we will disable resizing for the window:



self.window.resizable(0,0)


Enter fullscreen mode Exit fullscreen mode

step 6

Next, we give the window a title calculator.:



self.window.title('calculator')


Enter fullscreen mode Exit fullscreen mode

step 7

Next, we create (define) another method run that will run and start our calculator:



def run (self):
   self.window.mainloop()


Enter fullscreen mode Exit fullscreen mode

then outside this class we say:



if__name__ = "__main__":


Enter fullscreen mode Exit fullscreen mode

step 8

Next, inside this if statement we will create an object of the calculator class called calc:



calc = Calculator()


Enter fullscreen mode Exit fullscreen mode

Then we run the run method of calculator object:



calc.run() 


Enter fullscreen mode Exit fullscreen mode

Step 9

Save and run to see the image of the main window

Image of the main window


Creating the Frames

In this step we are going to create our frames.

Step 1

To do this, we are going to create 2 frames. One for the display and the other for the buttons:



self.display_frame = self.create_display_frame()
self.buttons_frame = self.create_buttons_frame()


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we define this 2 frames above,
first, we define display frame:



def create_display_frame(self):
    frame = tk.Frame(self.window,Height = 221,bg=
LIGHT_GRAY)                
    frame.pack(expand=True, fill='both')
    return frame


Enter fullscreen mode Exit fullscreen mode

(bg means background colour)

Step 3

Next, we will define button frame:



def create_button_frame(self):
   frame = tk.Frame(self.window)
   frame.pack(expand=True, full ="both")
   return frame


Enter fullscreen mode Exit fullscreen mode

Now that we have created the frames lets add display labels to our calculator.

Adding Display Labels

The calculator app will have 2 different labels, one to display the current expression and the other to create the total expression.

step 1

First, we define both the current expression and the total expression.:



self.total_expression ="0"
self.current_expression = "0"


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we create display labels to create this labels:



def create_display_labels(self):


Enter fullscreen mode Exit fullscreen mode

inside the method, we define the total label:



total_label = tk.Label(self.display_frame, text=self.total_expression, anchor =tk.E, bg = LIGHT_GRAY, fg=LABEL_COLOR, padx = 24, font= SMALL_FONT_STYLE)


Enter fullscreen mode Exit fullscreen mode

anchor =tk.E- This will help position the text at the East side of the frame

Step 3

Next, we pack this label with expand = true:



total_label.pack(expand=True, fill='both')

label = tk.Label(self.display_frame, text=self.current_expression, anchor =tk.E[[this will help position the text at the East side of the frame]], bg = LIGHT_GRAY, fg=LABEL_COLOR, padx = 24, font= LARGE_FONT_STYLE)total_label.pack(expand=True,fill='both')


Enter fullscreen mode Exit fullscreen mode

Finally, we return our display labels:



return total_label,label


Enter fullscreen mode Exit fullscreen mode

Step 4

Next we go back to the init method:



self.total_label,self.label = self.create_display_labels()


Enter fullscreen mode Exit fullscreen mode

Step 5

Save and run to see our calculator with display.

image of Calculator with display

Let's now add the buttons to our calculator.

Adding the Digit Buttons.

We use the grid system to add all the button.

Step 1

First we create a dictionary of all the digits in the corresponding positions.

In a standard calculator, the digits start from 7:



self.digits = {}


Enter fullscreen mode Exit fullscreen mode

So we add 7 first as the key with the value 1,1

7:(1,1) - we will later use this value to specify that 7 should be placed in a cell with role 1 and column 1.

similarly 8 should be placed in role 1 and column 2.



self.digits = {
7(1,1),8:(1,2),9:(1,3),4:(2,1),5:(2,2),6:(2,3),1:(3,1), 2:(3,2),3:(3,3)}


Enter fullscreen mode Exit fullscreen mode

we also have 0 at the centre of the last column ; 0:(4,2).
lets also add decimal point button ".":(4,1).

Step 2

Next, we create a method called 'create digit button':



def create_digit_buttons(self):


Enter fullscreen mode Exit fullscreen mode

Inside this method, we look through our dictionary and add each button to our button strings:



for digit,grid_value in self.digits.items():


Enter fullscreen mode Exit fullscreen mode

and for each of the digit and grid values, we create a button:



button =  tk,Button(self.buttons_frame, text=str(digit), bg= WHITE, fg = LABEL_COLOR, DIGITS_FONT_STYLE, borderwidth = 0)


Enter fullscreen mode Exit fullscreen mode

Step 3

Now, to place these button to the grid, we say:



button.grid()


Enter fullscreen mode Exit fullscreen mode

parsing through the first element of grid value which is [0] and the second element of grid value, which is [1]



button.grid(row=grid_value[0],column=grid_value[1])


Enter fullscreen mode Exit fullscreen mode

Step 4

Now we also specify sticky=tk.NSEW so that our buttons stick to every side and fill up the entire grid cell:



button.grid(row=grid_value[0], column=grid_value[1],sticky=tk.NSEW)


Enter fullscreen mode Exit fullscreen mode

Step 5

Next, we will call this method from inside init:



self.create_digit-buttons()


Enter fullscreen mode Exit fullscreen mode

Step 6

Save and run to see the image of digits in our calculator

Image of our calendar with digits


Next, let's add the basic operation buttons.

Adding the Operator Buttons

Here we want to add our calculator operator buttons + - / *

Step 1

To do this , first, we create a dictionary for several operations:



self.operations={"/":"\u00F7", "*": "\u00D7", "-": "-","+":"+"}


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we create a new method to create operations buttons:



def create_operator_buttons(self):
    for operator,symbol in self.operations.items():
       buttons =tk.Buttons,self.buttons_frame,
text=symbol, bg=OFF_WHITE, fg= LABEL_COLOR, font= DEFAULT_FONT_STYLE, borderwidth=0)


Enter fullscreen mode Exit fullscreen mode

Step 3

Next, let's place this button to button frame grid:



button.grid()


Enter fullscreen mode Exit fullscreen mode

We know that the operator button should be at the last column and it should start one role above the digit buttons.
so we first define a counter variable:



i = 0 
button.grid(row=1, column =4, sticky = tk.NSEW)


Enter fullscreen mode Exit fullscreen mode

Step 4

Next, we will increase the value of i by 1:



i += 1


Enter fullscreen mode Exit fullscreen mode

Then, we will call this method from inside the init method.

Step 5

Next, we will create Clear and equals button

To do this, first, we we define clear button and equals to:



def create_clear_button(self):
    button = tk.Button(self.buttons_frame, text="C", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, borderwidth =0)
    button.grid(row=0, column =1,columnspan=2, sticky=tk.NSEW)

def create_equals_button(self):
    button = tk.Button(self.buttons_frame, text="=", bg=LIGHT_BLUE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, borderwidth =0)
    button.grid(row=4,
column=3,columnspan=2,sticky=tk.NSEW)


Enter fullscreen mode Exit fullscreen mode

Step 6

Next, we call these above methods from the init method and to do that , we define a new method special buttons:



def create_special_buttons(self):


Enter fullscreen mode Exit fullscreen mode

inside this method we will call:



self.create_clear_button()
self.create_equals_button()


Enter fullscreen mode Exit fullscreen mode

Step 7

Next, we call the create_special_buttons:



self.create_special_buttons()


Enter fullscreen mode Exit fullscreen mode

Step 8

Now, let's increase the size of the digit button to fit the calculator frame.
First, we create a for loop that loops from 1-4:



self.buttons_frame.rowconfigure(0, weight=1)
       for x in range (1,5):
self.buttons_frame.rowconfigure(x, weight=1)
self.buttons_frame.columnconfigure, weight=1)


Enter fullscreen mode Exit fullscreen mode

Step 9

Save and run to see our calculator

Image of Calculator

Add functionality to the buttons

Let's start by making the digit button functional.

Step 1

First, we will create the method that creates the total and current label:



def update_total_label_label(self):
   self.label.configtext(text=self.current_expression)


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we are going to create a method called add to that adds a given value to current expression:



def add_to_expression(self,value):
      self.current_expression +=str(value)
      self.update_label()


Enter fullscreen mode Exit fullscreen mode

Step 3

now lets add the functionality of this method to our digit_buttons, and we will do that using lambda :



def create_digit_buttons(self):
    for digit,grid_value in self.digits.items():
       button =  tk,Button(self.buttons_frame, text=str(digit)[[when specifying the button text as digit, since its an integer value we converting to string]], bg= WHITE, fg = LABEL_COLOR, DIGITS_FONT_STYLE,borderwidth = 0, command=lambda x=digit: self.add_to_expression(x))


Enter fullscreen mode Exit fullscreen mode

[borderwidth = 0 - to remove the border of the buttons.]

Step 4

Finally, we will remove the initial value of self.total expression and self.current_expression:



 self.total_expression =""
 self.current_expression = ""   


Enter fullscreen mode Exit fullscreen mode

Step 5

Next, we add functionality to our operator buttons and to do this , we will implement a method called append operator:



def append_operator (self,operator):
     self.current_expression += operator
     self.total_expression += self.current_expression
     self.current_expression = ""
     self.update_total_label()
     self.update_label() 


Enter fullscreen mode Exit fullscreen mode

Step 6

Now, we add this method to our create_operator buttons:



def create_operator_buttons(self):
    for operator,symbol in self.operations.items():
    buttons =tk.Buttons(self,buttons_frame,
text=symbol, bg=OFF_WHITE, fg= LABEL_COLOR, font= DEFAULT_FONT_STYLE, borderwidth=0, command=lambda x=operator: self.append.operator(x))


Enter fullscreen mode Exit fullscreen mode

Now add functions to the clear and equals to button in a similar way.

Step 7

First, we will specify the clear method:



 def clear(self):
     self.current_expression = ""
     self.total_expression = ""
     self.update_label()
     self.update_total_label() 


Enter fullscreen mode Exit fullscreen mode

Step 8

Next, we add this method to our clear_button and specify command:



def create_clear_button(self):    
  button=tk.Button(self.buttons_frame,text="C",
bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, borderwidth =0, command=self.clear)


Enter fullscreen mode Exit fullscreen mode

Step 9

Next, we want to implement the functionality of theequals to button. To do this we have to use the eval function - The eval function evaluates and return the value of a valid python expression.
We are going to use this eval function to evaluate our total expression when the user presses the equals button.

To do this, first we define the evaluate method:



 def evaluate(self):
      self.total_expression += self.current_expression
      self.update_total_label()
self.total_expression=str(eval(self.total_expression))
      self.total_expression= "" 


Enter fullscreen mode Exit fullscreen mode

Step 10

Finally, we update the current label:



self.update_label()


Enter fullscreen mode Exit fullscreen mode

Step 11

Next, we add this method to our equals button and specify command:



def create_equals_button(self):
   button = tk.Button(self.buttons_frame, text="=", bg=LIGHT_BLUE, fg=LABEL_COLOR,font=DEFAULT_FONT_STYLE, borderwidth =0,command=self.evaluate)


Enter fullscreen mode Exit fullscreen mode

Step 12

Next save and run

Image of Calculator after adding functionalities to the buttons

Enhancing Calculator

Here we want to add advanced operators to our calculator adding square and square_root_Buttons:

Step 1

First, we create a square button and define a square method:



def square(self): 
     self.current_expression = str(eval(f"{self.current_expression}**2"))
     self.update_label()`

def create_square_button(self):
     button = tk.Button(self.buttons_frame, text="x\u00b2", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, borderwidth =0, command = self.square)
     button.grid(row=0, column =2,sticky=tk.NSEW)
```
</prev>

###Step 2

Similarly, we create the `square root button`:

<prev>
```python
def sqrt(self):
   self.current_expression = str(eval(f"{self.current_expression}**0.5"))
   self.update_label()

def create_sqrt_button(self):
      button = tk.Button(self.buttons_frame, text="\u00b2", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, borderwidth =0, command = self.sqrt)
      button.grid(row=0,colum =3,sticky=tk.NSEW)
```
</prev>

###Step 3

Next, we add these buttons into the `self.create special buttons` we created earlier:

<prev>
```python
 def create_special_buttons(self):
     self.create_clear_button()
     self.create_equals_button()
     self.create_square_button()
     self.create_sqrt_button()`


Enter fullscreen mode Exit fullscreen mode

Changing Operator Symbols

To change the operator symbols we go to the update total label and simply replace the python symbols to the actual operator symbols

Step 1

First, we define update total label:



def update_total_label(self):
   expression=self.total_expression for operator,
symbol in self.operations.items()
   expression=expression.replace(operator,f'{symbol}')
   self.total_label.config(text=expression)


Enter fullscreen mode Exit fullscreen mode

Truncating the results

When creating a calculator using Python, truncating the results means showing or giving back only a certain number of digits after the dot in the answer of a calculation. This helps to limit how precise the answer is, or to make it easier to understand.

For instance, if you have an answer like 3.14159265359 and you truncate it to two digits after the dot, the new answer will be 3.14.
To do this we go to the update label method and use slicing operator to limit its length to 11

Step 1



def update_labbel(self):
self.label.config(text=self.current_expression[:11]) 


Enter fullscreen mode Exit fullscreen mode

Handling Exceptions like ZeroDivisionError

This means making sure your calculator can handle errors that occur when trying to divide by zero.

Step 1

To handle exceptions we go to the evaluate method and i will put the eval function inside the 'try' block:



def evaluate(self):
      self.total_expression += self.current_expression
      self.update_total_label()
      try:
          self.total_expression = str(eval(self.total_expression))

           self.total_expression= ""
      except Exception as e:
            self.current_expression = "Error"
      finally:
            self.update_label() 


Enter fullscreen mode Exit fullscreen mode

Step 2

Save and run to see our final calculator

Final Calculator

Conclusion

Calculator with GUI Using Python Tkinter" is a rich resource that not only covers the technical aspects of GUI development but also delves into the logic and functionality behind building a fully operational calculator application. Readers are not only guided on how to design an aesthetically pleasing user interface but also learn the intricacies of event handling to ensure a seamless user experience. By breaking down the process of integrating mathematical operations and algorithms for arithmetic calculations, the tutorial empowers readers to not only replicate the calculator but also understand and modify its functionality to suit specific requirements.

Moreover, the tutorial serves as a bridge between theory and practice, offering a hands-on approach that allows readers to apply their knowledge immediately. By following the tutorial, programmers can gain proficiency in using Tkinter to create interactive applications and enhance their problem-solving skills through the implementation of mathematical logic in Python. The guidance provided enables readers to develop a foundational understanding of GUI application development while sparking their creativity to explore new features and functionalities beyond the basic calculator design.

In conclusion, "Calculator with GUI Using Python Tkinter" is a comprehensive tutorial that equips readers with the tools and knowledge necessary to develop functional and visually appealing GUI applications. From layout design to event handling and algorithm implementation, the tutorial covers a wide range of topics, making it an invaluable resource for individuals looking to expand their programming skills. By immersing themselves in the step-by-step instructions and practical examples, readers can explore the exciting world of GUI development using Python and Tkinter, paving the way for future projects and learning opportunities in interactive application development.

Top comments (5)

Collapse
 
emmasmiths profile image
Emma

Thank you very much for such informative post. Can you write article on topic starbucks calorie calculator as they have did it. Thank you much if you can help me.

Collapse
 
emmasmiths profile image
Emma

Kindly reply as soon as possible.

Collapse
 
spiff profile image
Ebikara Spiff

Hey Emma, I just wrote the article I promised, I hope you find it useful

Collapse
 
spiff profile image
Ebikara Spiff

Thank you for your compliment on my article Emma.
I will write an article on your request before the end of the week.

Collapse
 
emmasmiths profile image
Emma

Have a look on my new application which is qr code scanner