In this tutorial, we’ll create a pro-style calculator using Python's Tkinter library. It will feature:
A sleek dark theme
Input via buttons or keyboard
Result display
Calculation history (last 10 calculations)
Let’s dive in step by step.
Step 1: Import Tkinter and Setup
First, we import Tkinter and messagebox for alerts. Then, we define a theme for our app.
import tkinter as tk
from tkinter import messagebox
# =========================
# THEME COLORS
# =========================
APP_BG = "#121212"
PANEL_BG = "#1F1F1F"
BTN_BG = "#2C2C2C"
BTN_HOVER = "#3A3A3A"
BTN_ACTIVE = "#FF6F61"
ACCENT = "#FF6F61"
TEXT_CLR = "#E0E0E0"
SUBTEXT_CLR = "#AAAAAA"
INPUT_BG = "#333333"
INPUT_FG = "#FFFFFF"
Explanation:
We define a set of colors to give our app a modern dark look. Using constants makes it easy to change the theme later.
Step 2: Create the Main App Class
We will wrap the entire calculator in a class to keep our code organized.
class CalculatorApp:
def __init__(self, root):
self.root = root
root.title("MateTools – Pro Calculator")
root.geometry("1000x500")
root.configure(bg=APP_BG)
root.resizable(False, False)
Explanation:
root is the main Tkinter window.
We set the title, size, background, and prevent resizing.
Using a class makes it easier to manage methods and UI components.
Step 3: Build the Left Panel (Actions)
The left panel will contain buttons for clearing input, clearing history, and About.
# LEFT PANEL
left = tk.Frame(root, bg=PANEL_BG, width=420)
left.pack(side="left", fill="y")
# Header
header = tk.Frame(left, bg=PANEL_BG)
header.pack(fill="x", padx=16, pady=(18, 10))
tk.Label(header, text="MateTools", bg=PANEL_BG, fg=ACCENT, font=("Segoe UI", 20, "bold")).pack(side="left")
# Subheader
tk.Label(left, text="Pro Calculator", bg=PANEL_BG, fg=TEXT_CLR, font=("Segoe UI", 14, "bold")).pack(anchor="w", padx=16, pady=(0, 2))
tk.Label(left, text="Perform calculations with history", bg=PANEL_BG, fg=SUBTEXT_CLR, font=("Segoe UI", 10)).pack(anchor="w", padx=16, pady=(0, 16))
Explanation:
We create a vertical left panel with a header and subtext. Tkinter’s Frame allows grouping UI elements together.
Step 4: Add Action Buttons with Hover Effects
We’ll create a helper function to make buttons reusable with hover and click effects.
def make_btn(text, cmd, color=BTN_BG):
btn = tk.Button(
left, text=text, command=cmd, bg=color, fg="white",
font=("Segoe UI", 11, "bold"), relief="flat", height=2, width=20
)
btn.bind("<Enter>", lambda e: btn.config(bg=BTN_HOVER))
btn.bind("<Leave>", lambda e: btn.config(bg=color))
btn.bind("<ButtonPress-1>", lambda e: btn.config(bg=BTN_ACTIVE))
btn.bind("<ButtonRelease-1>", lambda e: btn.config(bg=BTN_HOVER))
return btn
make_btn("Clear Input", self.clear_input, ACCENT).pack(pady=8)
make_btn("Clear History", self.clear_history).pack(pady=8)
make_btn("About", self.show_about).pack(pady=20)
Explanation:
make_btn creates buttons with hover and active states.
We reuse it for multiple buttons to avoid repeating code.
Step 5: Create the Right Panel (Calculator UI)
The right panel contains input, buttons, result, and history.
right = tk.Frame(root, bg=APP_BG)
right.pack(side="right", fill="both", expand=True)
# Result Card
self.result_card = tk.Frame(right, bg=PANEL_BG, bd=2, relief="ridge")
self.result_card.pack(padx=30, pady=20, fill="both", expand=True)
tk.Label(self.result_card, text="Calculator", bg=PANEL_BG, fg=TEXT_CLR, font=("Segoe UI", 18, "bold")).pack(pady=(20, 10))
Explanation:
The right frame expands to fill available space.
result_card is a card-like frame to hold calculator UI components.
Step 6: Add Input Field and Button Grid
We’ll create an entry widget and a grid of buttons for digits and operators.
# Input Entry
self.input_var = tk.StringVar()
self.input_entry = tk.Entry(self.result_card, textvariable=self.input_var, bg=INPUT_BG, fg=INPUT_FG, font=("Segoe UI", 18), relief="flat", justify="right")
self.input_entry.pack(fill="x", pady=(0, 10))
self.input_entry.bind("<Return>", lambda event: self.calculate())
# Buttons
buttons = [
('7', '8', '9', '/'),
('4', '5', '6', '*'),
('1', '2', '3', '-'),
('0', '.', '=', '+'),
]
for r, row in enumerate(buttons):
for c, char in enumerate(row):
action = self.calculate if char == '=' else lambda ch=char: self.add_to_input(ch)
tk.Button(self.result_card, text=char, width=5, height=2, command=action).grid(row=r, column=c, padx=5, pady=5)
Explanation:
Entry allows typing expressions.
Grid buttons make input easy with mouse clicks.
= button triggers calculation.
Step 7: Add Result Display and History
We’ll show the current result and last 10 calculations.
# Result label
self.result_label = tk.Label(self.result_card, text="--", bg=PANEL_BG, fg=ACCENT, font=("Segoe UI", 18, "bold"))
self.result_label.pack(anchor="e", padx=10, pady=(0, 5))
# History listbox
self.history_box = tk.Listbox(self.result_card, bg=INPUT_BG, fg=INPUT_FG, font=("Segoe UI", 12), height=10)
self.history_box.pack(fill="both", expand=True, padx=10, pady=(0, 10))
self.history = []
Explanation:
result_label shows the latest calculation result.
Listbox displays the last 10 calculations.
Step 8: Add Core Methods
These methods handle input, calculation, and history management.
def add_to_input(self, char):
self.input_var.set(self.input_var.get() + char)
def calculate(self):
expr = self.input_var.get()
if not expr.strip():
return
try:
result = round(eval(expr), 6)
self.result_label.config(text=str(result))
self.history.append(f"{expr} = {result}")
self.history = self.history[-10:]
self.update_history()
self.input_var.set(str(result))
except Exception as e:
messagebox.showerror("Error", f"Invalid expression: {e}")
def update_history(self):
self.history_box.delete(0, tk.END)
for item in self.history:
self.history_box.insert(tk.END, item)
def clear_input(self):
self.input_var.set("")
def clear_history(self):
self.history = []
self.update_history()
def show_about(self):
messagebox.showinfo("About", "MateTools – Pro Calculator\nBuilt by MateTools")
Explanation:
add_to_input appends button presses to the entry.
calculate evaluates the expression safely and updates history.
clear_input and clear_history reset fields.
show_about shows an info dialog.
Step 9: Run the App
Finally, instantiate the class and run the Tkinter main loop.
if __name__ == "__main__":
root = tk.Tk()
CalculatorApp(root)
root.mainloop()
Explanation:
Creates the main window and runs the app.
Everything is neatly organized inside CalculatorApp.
✅ Congrats! You now have a modern, dark-themed calculator with input, buttons, results, and history.

Top comments (0)