Frontend Development 20 min read

Build a Feature‑Rich Python Calculator with Tkinter – Full Code & Walkthrough

Learn how to create a fully functional Python calculator using Tkinter, covering complete requirements, UI design, button layout, advanced math operations, dynamic font scaling, keyboard handling, and extensibility suggestions, with the entire source code and detailed explanations for each component.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Build a Feature‑Rich Python Calculator with Tkinter – Full Code & Walkthrough

Functional Requirements

The calculator should support basic arithmetic (addition, subtraction, multiplication, division), advanced operations (square root, percentage, exponentiation), trigonometric functions (sin, cos, tan), logarithmic functions (natural log and common log), the constant π, a clear display area with history, responsive button colors, keyboard input, and user instructions.

Complete Code and Execution

Copy the following code into a

.py

file and run it with

python filename.py

. No external libraries are required.

import tkinter as tk
from tkinter import font
import math
import re

class Calculator:
    def __init__(self, root):
        self.root = root
        self.root.title("高级计算器")
        self.root.geometry("400x600")
        self.root.resizable(False, False)
        self.root.configure(bg="#f0f0f0")
        self.display_font = font.Font(family="SimHei", size=24)
        self.button_font = font.Font(family="SimHei", size=14)
        self.current_expression = ""
        self.last_result = ""
        self.is_new_calculation = True
        self._create_display()
        self._create_buttons()
        self.root.bind("<Key>", self._handle_key_event)

    def _create_display(self):
        self.history_frame = tk.Frame(self.root, bg="#f0f0f0", height=50)
        self.history_frame.pack(fill=tk.X, padx=10, pady=(10, 0))
        self.history_frame.pack_propagate(0)
        self.history_label = tk.Label(self.history_frame, text="", bg="#f0f0f0", fg="#888", font=self.display_font, anchor=tk.E)
        self.history_label.pack(fill=tk.BOTH, padx=5)

        self.display_frame = tk.Frame(self.root, bg="#f0f0f0", height=80)
        self.display_frame.pack(fill=tk.X, padx=10, pady=5)
        self.display_frame.pack_propagate(0)
        self.display = tk.Entry(self.display_frame, font=self.display_font, bg="white", fg="black", justify=tk.RIGHT, bd=5, relief=tk.SUNKEN, state="readonly")
        self.display.pack(fill=tk.BOTH, padx=5, pady=5)
        self.display.insert(0, "0")
        self.display.configure(state="readonly")

    def _create_buttons(self):
        button_frame = tk.Frame(self.root, bg="#f0f0f0")
        button_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        buttons = [
            ("7",1,0), ("8",1,1), ("9",1,2), ("/",1,3), ("C",1,4),
            ("4",2,0), ("5",2,1), ("6",2,2), ("*",2,3), ("⌫",2,4),
            ("1",3,0), ("2",3,1), ("3",3,2), ("-",3,3), ("(",3,4),
            ("0",4,0), (".",4,1), ("=",4,2), ("+",4,3), (")",4,4),
            ("%",5,0), ("√",5,1), ("^",5,2), ("π",5,3), ("sin",5,4),
            ("cos",6,0), ("tan",6,1), ("ln",6,2), ("log",6,3), ("1/x",6,4)
        ]
        for text, row, col in buttons:
            if text == "=":
                bg_color, fg_color = "#4CAF50", "white"
            elif text in ("C", "⌫"):
                bg_color, fg_color = "#f44336", "white"
            elif col in (3,4):
                bg_color, fg_color = "#2196F3", "white"
            else:
                bg_color, fg_color = "#e0e0e0", "black"
            button = tk.Button(button_frame, text=text, font=self.button_font, bg=bg_color, fg=fg_color,
                               relief=tk.RAISED, bd=3, padx=10, pady=10,
                               command=lambda txt=text: self._button_click(txt))
            button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
        for i in range(7):
            button_frame.grid_rowconfigure(i, weight=1)
        for i in range(5):
            button_frame.grid_columnconfigure(i, weight=1)

    def _button_click(self, text):
        if text == "C":
            self._clear_all()
        elif text == "⌫":
            self._backspace()
        elif text == "=":
            self._calculate()
        elif text == "π":
            self._append_value(str(math.pi))
        elif text == "√":
            self._calculate_sqrt()
        elif text == "^":
            self._append_value("**")
        elif text in ("sin", "cos", "tan"):
            self._calculate_trig(text)
        elif text == "ln":
            self._calculate_ln()
        elif text == "log":
            self._calculate_log()
        elif text == "1/x":
            self._calculate_reciprocal()
        elif text == "%":
            self._calculate_percentage()
        else:
            self._append_value(text)

    def _handle_key_event(self, event):
        key = event.char
        if key.isdigit() or key in "+-*/().":
            self._append_value(key)
        elif key in ("\r", "="):
            self._calculate()
        elif key == "\x08":
            self._backspace()
        elif key.lower() == "c":
            self._clear_all()

    # ... Additional methods for _append_value, _clear_all, _backspace, _update_display,
    # _calculate, _calculate_sqrt, _calculate_trig, _calculate_ln, _calculate_log,
    # _calculate_reciprocal, _calculate_percentage are defined similarly, handling
    # expression parsing, error catching, history updates, and display refresh.

if __name__ == "__main__":
    root = tk.Tk()
    app = Calculator(root)
    root.mainloop()

Running the Application

Open a command prompt, type

python

followed by a space, drag the saved file into the window, and press Enter. The calculator window will appear.

Calculator UI screenshot
Calculator UI screenshot

Code Walkthrough

The application is built with an object‑oriented structure. The

Calculator

class creates and manages the GUI, processes user input (both button clicks and keyboard events), performs calculations, and updates the display.

Overall Architecture: The class initializes the root window, sets title, size, and background, and defines fonts.

Display Area: Two sections – a history label showing the previous expression and result, and a read‑only entry showing the current expression.

Button Layout: Buttons are defined in a list and placed on a 6×5 grid. Colors differentiate functions: green for “=”, red for clear/backspace, blue for operators, gray for digits.

Core Calculation:

eval()

evaluates the expression after replacing π and e. Results are formatted to avoid long floating‑point strings.

Advanced Functions: Separate methods handle square root, trigonometric functions (with degree‑to‑radian conversion), natural and common logarithms, reciprocal, and percentage calculations, each with error handling.

User Input:

_button_click

routes button actions;

_handle_key_event

maps keyboard keys to the same logic, supporting digits, operators, Enter, Backspace, and clear.

Dynamic Font Adjustment: If the expression exceeds 15 characters, the font size shrinks from 24 pt to 18 pt to keep the whole expression visible.

Program Entry: The standard

if __name__ == "__main__"

block creates the Tkinter root and starts the main event loop.

Extension Ideas

Add memory buttons (M+, M-, MR, MC) for storing values.

Implement scientific notation for very large or small results.

Provide base conversion (binary, octal, decimal, hexadecimal).

Show matching parentheses with color cues.

Store multiple history entries and allow reusing them.

GUIPythonprogrammingDesktop ApplicationTkinterCalculatorCode Tutorial
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.