In this tutorial, we’ll create a visually appealing BMI Calculator using Python’s Tkinter library. This guide is beginner-friendly, with step-by-step explanations and code snippets.
- Import Required Modules
We need some standard Python libraries:
import sys
import os
import tkinter as tk
from tkinter import messagebox
tkinter: For building the GUI.
messagebox: For showing pop-up messages like errors or info.
sys and os: Useful for future extensions (optional here).
- Define Theme Colors and Font
To make our app look modern, we’ll define colors and fonts as constants:
# =========================
# THEME
# =========================
APP_BG = "#121212" # Main background
PANEL_BG = "#1F1F1F" # Panels background
BTN_BG = "#2C2C2C" # Button background
ACCENT = "#FF6F61" # Accent color for highlights
TEXT_CLR = "#E0E0E0" # Primary text color
SUBTEXT_CLR = "#AAAAAA" # Secondary text color
INPUT_BG = "#333333" # Input field background
INPUT_FG = "#FFFFFF" # Input field text
FONT = ("Segoe UI", 11) # Default font
This helps centralize styling, so it’s easier to update later.
- Initialize the Main App Window
We’ll create the main window and set its title, size, and background color:
class BMICalculatorApp:
def __init__(self, root):
self.root = root
root.title("MateTools – BMI Calculator")
root.geometry("1000x520")
root.configure(bg=APP_BG)
root.resizable(False, False) # Fix window size
root.resizable(False, False) prevents the window from being resized.
root.configure(bg=APP_BG) sets a dark theme background.
- Create the Left Panel
The left panel will contain inputs and buttons.
# Left panel
left = tk.Frame(root, bg=PANEL_BG, width=420)
left.pack(side="left", fill="y")
Header in Left Panel
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")
We added a title with the accent color.
pady and padx add spacing.
Section Divider
tk.Frame(left, bg=ACCENT, height=2).pack(fill="x", padx=16, pady=(0, 14))
A thin line to visually separate the header from the rest of the panel.
Add Panel Title and Description
tk.Label(left, text="BMI Calculator", bg=PANEL_BG, fg=TEXT_CLR, font=("Segoe UI", 14, "bold")).pack(anchor="w", padx=16, pady=(0, 2))
tk.Label(left, text="Calculate your Body Mass Index", bg=PANEL_BG, fg=SUBTEXT_CLR, font=("Segoe UI", 10)).pack(anchor="w", padx=16, pady=(0, 16))
- Add Input Fields
We need height and weight inputs:
input_frame = tk.Frame(left, bg=PANEL_BG)
input_frame.pack(padx=16, pady=16, fill="x")
tk.Label(input_frame, text="Height (cm):", bg=PANEL_BG, fg=TEXT_CLR, font=FONT).pack(anchor="w")
self.height_entry = tk.Entry(input_frame, bg=INPUT_BG, fg=INPUT_FG, font=FONT)
self.height_entry.pack(fill="x", pady=(0, 10))
tk.Label(input_frame, text="Weight (kg):", bg=PANEL_BG, fg=TEXT_CLR, font=FONT).pack(anchor="w")
self.weight_entry = tk.Entry(input_frame, bg=INPUT_BG, fg=INPUT_FG, font=FONT)
self.weight_entry.pack(fill="x", pady=(0, 10))
tk.Entry is used for user input.
Each input is labeled for clarity.
- Add Buttons
We create a reusable button function:
btn_frame = tk.Frame(left, bg=PANEL_BG)
btn_frame.pack(fill="x", padx=16, pady=16)
def make_btn(text, cmd, color=BTN_BG):
return tk.Button(
btn_frame,
text=text,
command=cmd,
bg=color,
fg="white",
font=("Segoe UI", 11, "bold"),
relief="flat",
height=2,
width=18
)
make_btn("Calculate BMI", self.calculate_bmi, ACCENT).pack(side="left", expand=True, padx=4)
make_btn("About", self.show_about, BTN_BG).pack(side="left", expand=True, padx=4)
self.calculate_bmi will handle BMI calculations.
self.show_about will show app info.
- Create Right Panel (Results Display)
right = tk.Frame(root, bg=APP_BG)
right.pack(side="right", fill="both", expand=True)
self.result_card = tk.Frame(right, bg=PANEL_BG)
self.result_card.pack(padx=30, pady=40, fill="both", expand=True)
tk.Label(self.result_card, text="Your BMI Result", bg=PANEL_BG, fg=TEXT_CLR, font=("Segoe UI", 16, "bold")).pack(pady=(20, 10))
self.bmi_value_label = tk.Label(self.result_card, text="--", bg=PANEL_BG, fg=ACCENT, font=("Segoe UI", 40, "bold"))
self.bmi_value_label.pack(pady=(10, 5))
self.bmi_status_label = tk.Label(self.result_card, text="Enter your height and weight to calculate BMI", bg=PANEL_BG, fg=SUBTEXT_CLR, font=("Segoe UI", 16, "bold"))
self.bmi_status_label.pack(pady=(5, 20))
Shows the BMI value and status.
Initially, the BMI is set to --.
- Add BMI Progress Bar
self.bmi_bar_bg = tk.Frame(self.result_card, bg="#333333", height=30)
self.bmi_bar_bg.pack(fill="x", padx=40, pady=(10, 0))
self.bmi_bar_fg = tk.Frame(self.bmi_bar_bg, bg=ACCENT, width=0, height=30)
self.bmi_bar_fg.place(x=0, y=0)
A visual indicator of BMI.
We update self.bmi_bar_fg dynamically after calculation.
Add Labels Along the Bar
self.bmi_labels_frame = tk.Frame(self.result_card, bg=PANEL_BG)
self.bmi_labels_frame.pack(fill="x", padx=40, pady=(5, 0))
tk.Label(self.bmi_labels_frame, text="Underweight", bg=PANEL_BG, fg="#87CEEB", font=("Segoe UI", 10)).pack(side="left")
tk.Label(self.bmi_labels_frame, text="Normal", bg=PANEL_BG, fg="#32CD32", font=("Segoe UI", 10)).pack(side="left", expand=True)
tk.Label(self.bmi_labels_frame, text="Overweight", bg=PANEL_BG, fg="#FFD700", font=("Segoe UI", 10)).pack(side="left")
tk.Label(self.bmi_labels_frame, text="Obesity", bg=PANEL_BG, fg="#FF4500", font=("Segoe UI", 10)).pack(side="right")
Color-coded labels match the BMI categories.
- Calculate BMI
def calculate_bmi(self):
try:
height_cm = float(self.height_entry.get())
weight_kg = float(self.weight_entry.get())
if height_cm <= 0 or weight_kg <= 0:
raise ValueError
height_m = height_cm / 100
bmi = weight_kg / (height_m ** 2)
bmi = round(bmi, 2)
if bmi < 18.5:
status, color = "Underweight", "#87CEEB"
elif bmi < 25:
status, color = "Normal weight", "#32CD32"
elif bmi < 30:
status, color = "Overweight", "#FFD700"
else:
status, color = "Obesity", "#FF4500"
self.bmi_value_label.config(text=str(bmi), fg=color)
self.bmi_status_label.config(text=status, fg=color)
max_width = self.bmi_bar_bg.winfo_width() or 400
bmi_width = min(bmi / 40, 1) * max_width
self.bmi_bar_fg.config(width=bmi_width, bg=color)
except ValueError:
messagebox.showerror("Invalid input", "Please enter valid numeric values for height and weight.")
Converts cm to meters.
Uses BMI formula: weight / height².
Dynamically updates the label and progress bar color.
- About Dialog
def show_about(self):
messagebox.showinfo(
"About",
"MateTools – BMI Calculator\n\n"
"• Calculate Body Mass Index (BMI)\n"
"• Provides BMI category with color-coded visual\n\n"
"Built by MateTools"
)
Simple pop-up to explain the app.
- Run the App
if __name__ == "__main__":
root = tk.Tk()
BMICalculatorApp(root)
root.mainloop()
Initializes Tkinter main loop.
Starts the BMI calculator GUI.
✅ Now you have a fully functional BMI Calculator with a modern dark theme, interactive input, and a visual progress bar.

Top comments (0)