How To Make A Simple Calculator In Python Using Customtkinter

Hello Pythonistas, welcome back. I hope you are doing well.

This is the 4th Project in our series CodeCraft: Building Skills One Project at a Time.

The first project in this series was making a command line-based calculator.

Today we will be building that with a Modern Graphical User Interface.

Although there is already a complete GUI calculator tutorial on the website, this one is the simpler one.

That one is worth checking once.

Now let’s get started with creating a Simple Calculator In Python Using Customtkinter.

The result would be a simple calculator which would look like this.

Output: Simple Calculator In Python Using Customtkinter

Pre-requisites

Kindly, go thoroughly through the code of the calculator we created in the first article of the code craft series.

That’s it.

Why Calculator Again?

This way you would be able to create add-ons to your existing projects in the future.

Also, it’s the best way to lay your foundation for GUI’s and OOP.

Approach To Create A Simple Calculator In Python Using Customtkinter

  1. Create GUI
    • We will first create 2 entry widgets to get the numbers.
    • We will create 4 buttons to perform operations.
    • Next, we will create a label to display the result.
  2. After this, we will integrate the code of the calculate function that we created.
  3. Finally, we will Fetch values from UI, then call the calculate function and display the results.
    • Get the numbers
    • Calculate the results
    • Display the results
    • Clean the inputs

Step 1: Create GUI

from customtkinter import *
# Step 1: Create GUI
class CalculatorGui(CTk):
    def __init__(self):
        super().__init__()
        self.build_widget()
    
    def build_widget(self):
        pass

# create object of the class
if __name__ == "__main__":
    app = CalculatorGui()
    app.mainloop()

To understand this code line by line click here.

Step 1.1: Create 2 entry widgets

def build_widget(self):
        # Step 1.1: Create 2 entry widgets
        self.num1Label = CTkLabel(master=self, text="Enter 1st Num: ")
        self.num1Label.grid(row=0, column=0, padx=10, pady=10)
        self.num1 = CTkEntry(master=self)
        self.num1.grid(row=0, column=1, padx=10, pady=10)
        
        self.num1Label = CTkLabel(master=self, text="Enter 2nd Num: ")
        self.num1Label.grid(row=1, column=0, padx=10, pady=10)
        self.num2 = CTkEntry(master=self)
        self.num2.grid(row=1, column=1, padx=10, pady=10)

To understand the Entry(Input) widget in CustomTkinter click here.

Step 1.2: Create 4 buttons

        # Step 1.2: Create 4 buttons
        self.add_button = CTkButton(master=self, text="(+)")
        self.sub_button = CTkButton(master=self, text="(-)")
        self.mul_button = CTkButton(master=self, text="(x)")
        self.div_button = CTkButton(master=self, text="(/)")

        self.add_button.grid(row=2, column=0, padx=10, pady=10)
        self.sub_button.grid(row=2, column=1, padx=10, pady=10)
        self.mul_button.grid(row=3, column=0, padx=10, pady=10)
        self.div_button.grid(row=3, column=1, padx=10, pady=10)

To understand the Button widget in CustomTkinter click here.

Step 1.3: Create a label for output.

# Step 1.3: Create label for output.
        self.result = CTkLabel(master=self, text="Result Would be here")
        self.result.grid(row=4, column=0, padx=10, pady=10)

To understand the Label widget in CustomTkinter click here.

On pressing any button we would need to call the function calculate that we created in the previous project.

Step 2: Now we need to get the calculate function.

Don’t forget to add the self argument to it.

# Step 2: Now we need to get the calculate function. 
    def calculate(self, n1:float, n2:float, operator:str) -> float:
        operator_match = {
            "+": n1+n2,
            "-": n1-n2,
            "x": n1*n2,
            "/": n1/n2,
        }
        return operator_match[operator]

But that function takes 3 values, num1, num2, and operator.

We need to create a function that fetches the values in the entry widgets and then provides them to the calculate function.

This function should also remove the existing values from the entry widgets. And it should also update the result.

Step 3: Integrate UI with logic

We would call this function on all the buttons.

    # Step 3: Integrate UI with logic
    def fetch_values(self, operator: str):
        res_string = ""

Step 3.1: Get the numbers Calculate the results

        # Step 3.1: getting the numbers
        try:
            f_num = float(self.num1.get())
            s_num = float(self.num2.get())
            # Step 3.2: Calculate the results
            res = self.calculate(f_num, s_num, operator)
            res_string = f"{f_num} {operator} {s_num} = {str(res)}"
        except ValueError:
            res_string = "Enter Valid Values!!"

Step 3.2: Display the results

# Step 3.3: Display the results
        self.result.grid_forget()
        self.result = CTkLabel(master=self, text=res_string)
        self.result.grid(row=4, column=0, padx=10, pady=10)

Step 3.3: Clear the entry widgets.

# Step 3.4: Clear the entry widgets.
        self.num1.delete(0, END)
        self.num2.delete(0, END)

Step 3.4: Call the function in the buttons

        self.add_button = CTkButton(master=self, text="(+)", command=lambda: self.fetch_values("+"))
        self.sub_button = CTkButton(master=self, text="(-)", command=lambda: self.fetch_values("-"))
        self.mul_button = CTkButton(master=self, text="(x)", command=lambda: self.fetch_values("x"))
        self.div_button = CTkButton(master=self, text="(/)", command=lambda: self.fetch_values("/"))

We have used a lambda function as the fetch_values method takes an argument operator.

Full Source Code

Click Here
from customtkinter import *
# Step 1: Create GUI
class CalculatorGui(CTk):
    def __init__(self):
        super().__init__()
        self.build_widget()
    
    def build_widget(self):
        # Step 1.1: Create 2 entry widgets
        self.num1Label = CTkLabel(master=self, text="Enter 1st Num: ")
        self.num1Label.grid(row=0, column=0, padx=10, pady=10)
        self.num1 = CTkEntry(master=self)
        self.num1.grid(row=0, column=1, padx=10, pady=10)

        self.num1Label = CTkLabel(master=self, text="Enter 2nd Num: ")
        self.num1Label.grid(row=1, column=0, padx=10, pady=10)
        self.num2 = CTkEntry(master=self)
        self.num2.grid(row=1, column=1, padx=10, pady=10)

        # Step 1.2: Create 4 buttons
        self.add_button = CTkButton(master=self, text="(+)", command=lambda: self.fetch_values("+"))
        self.sub_button = CTkButton(master=self, text="(-)", command=lambda: self.fetch_values("-"))
        self.mul_button = CTkButton(master=self, text="(x)", command=lambda: self.fetch_values("x"))
        self.div_button = CTkButton(master=self, text="(/)", command=lambda: self.fetch_values("/"))

        self.add_button.grid(row=2, column=0, padx=10, pady=10)
        self.sub_button.grid(row=2, column=1, padx=10, pady=10)
        self.mul_button.grid(row=3, column=0, padx=10, pady=10)
        self.div_button.grid(row=3, column=1, padx=10, pady=10)

        # Step 1.3: Create label for output.
        self.result = CTkLabel(master=self, text="Result Would be here")
        self.result.grid(row=4, column=0, padx=10, pady=10)

    # Step 2: Now we need to call the function. 
    def calculate(self, n1:float, n2:float, operator:str) -> float:
        operator_match = {
            "+": n1+n2,
            "-": n1-n2,
            "x": n1*n2,
            "/": n1/n2,
        }
        return operator_match[operator]
    # Step 3: Integrate UI with logic
    def fetch_values(self, operator):
        res_string = ""
        # Step 3.1: getting the numbers
        try:
            f_num = float(self.num1.get())
            s_num = float(self.num2.get())
            # Step 3.2: Calculate the results
            res = self.calculate(f_num, s_num, operator)
            res_string = f"{f_num} {operator} {s_num} = {str(res)}"
        except ValueError:
            res_string = "Enter Valid Values!!"


        # Step 3.3: Display the results
        self.result.grid_forget()
        self.result = CTkLabel(master=self, text=res_string)
        self.result.grid(row=4, column=0, padx=10, pady=10)

        # Step 3.4: Clear the entry widgets.
        self.num1.delete(0, END)
        self.num2.delete(0, END)




# create object of the class
if __name__ == "__main__":
    app = CalculatorGui()
    app.mainloop()

Challenge For You!

Handle the division by zero case and display a history of calculations.

Leave a Reply