expense tracer in python using GUI

introduction
Tracking daily expenses is a vital part of personal financial management. Whether you’re a student budgeting your monthly allowance, a professional managing household bills, or someone planning to save for a goal, knowing where your money goes is the first step toward better control over your finances.
This project is a GUI-based Expense Tracker in python built using Python’s Tkinter library, designed to run smoothly within a Jupyter Notebook environment (or as a standalone script). It enables users to easily input and monitor their expenses, categorized by description and type, while also displaying the total amount spent.
Why This Project?
Many people rely on manual methods like notebooks or spreadsheets to track spending. However expense tracer in python performs, such methods can be time-consuming and error-prone. This project offers a simple, user-friendly interface where:
-
You can input description, category, and amount for each expense.
-
See a running list of all recorded expenses in a table format.
-
Get a real-time total of all expenses displayed below the table.
It is ideal for:
-
Students tracking hostel, tuition, and meal costs.
-
Freelancers managing recurring subscriptions or equipment expenses.
-
Anyone trying to build financial discipline and avoid overspending.
With just a few lines of Python code, this expense tracker becomes a handy tool to build financial awareness without needing spreadsheets, cloud tools, or advanced financial apps.
Features:
-
Clean and minimal Tkinter-based GUI
-
Input fields for description, category, and amount
-
Treeview table to show the list of expenses
-
Automatically calculates and shows total expense
-
User input validation and error alerts using
messagebox
steps to create expense tracer in python
Step 1: Import Required Libraries
Begin by importing the essential modules for GUI and user interaction.
import tkinter as tk
from tkinter import ttk, messagebox
tkinter
: Used to build the GUI components (buttons, labels, entries, etc.).ttk
: Provides theTreeview
widget for displaying expenses in a table format.messagebox
: Shows pop-up error messages for invalid inputs.
Step 2: Initialize the Main GUI Window
Create and configure the root window for your GUI application.
root = tk.Tk()
root.title("Expense Tracker")
root.geometry("500x500")
root.config(bg="white")
title()
sets the window title.geometry()
defines the window size.bg="white"
sets the background color.
Step 3: Create a List to Store Expenses
You’ll use a list to temporarily hold all added expenses.
expenses = []
Each expense will be a tuple of (description, category, amount)
.
Step 4: Define a Function to Add New Expenses
This function captures the input from entry fields, validates it, adds the expense to the list, and updates the display.
def add_expense():
desc = desc_entry.get()
category = category_entry.get()
amount = amount_entry.get()
...
Checks for empty fields.
Converts the amount to float and handles errors.
Appends the new expense to the
expenses
list.Clears the input fields after successful entry.
Step 5: Define a Function to Update the Expense List Table
This function refreshes the Treeview
to display all recorded expenses in table format.
def update_expense_list():
for row in tree.get_children():
tree.delete(row)
for i, (desc, category, amount) in enumerate(expenses, start=1):
tree.insert("", "end", values=(i, desc, category, f"${amount:.2f}"))
Clears the table before updating it.
Iterates through the expense list and adds each entry.
Step 6: Define a Function to Calculate and Display Total
Calculates the sum of all expense amounts and updates the total label.
def update_total():
total = sum(amount for _, _, amount in expenses)
total_label.config(text=f"Total: ${total:.2f}")
Step 7: Create GUI Entry Fields and Buttons
Set up input fields for description, category, and amount, and a button to trigger add_expense()
.
tk.Label(root, text="Description", bg="white").pack()
desc_entry = tk.Entry(root, width=40)
desc_entry.pack()
tk.Label(root, text="Category", bg="white").pack()
category_entry = tk.Entry(root, width=40)
category_entry.pack()
tk.Label(root, text="Amount ($)", bg="white").pack()
amount_entry = tk.Entry(root, width=40)
amount_entry.pack()
add_btn = tk.Button(root, text="Add Expense", command=add_expense, bg="#4CAF50", fg="white")
add_btn.pack(pady=10)
Step 8: Create the Table to Show Expenses
Use a Treeview
table to list the added expenses in rows.
columns = ("#", "Description", "Category", "Amount")
tree = ttk.Treeview(root, columns=columns, show="headings")
for col in columns:
tree.heading(col, text=col)
tree.pack(pady=10, fill="x")
Step 9: Create a Label for Total Expenses
Displays the cumulative sum of all expenses.
total_label = tk.Label(root, text="Total: $0.00", font=("Arial", 12, "bold"), bg="white", fg="green")
total_label.pack(pady=10)
Step 10: Start the GUI Event Loop
This keeps the GUI running and responsive.
root.mainloop()
code explanation
1. Import Required Libraries
import tkinter as tk
from tkinter import ttk, messagebox
tkinter
: For creating GUI elements like buttons, labels, entries.ttk
: For theTreeview
widget, which displays data in a tabular format.messagebox
: For pop-up error messages when input is invalid.
2. Create and Configure the Main Window
root = tk.Tk()
root.title("Expense Tracker")
root.geometry("500x500")
root.config(bg="white")
Tk()
: Creates the main application window.title()
: Sets the window title.geometry()
: Defines window size (width x height).bg="white"
: Sets a clean white background.
3. Create the Expense Storage List
expenses = []
A list to store each expense entry as a tuple:
(description, category, amount)
.
4. Define the add_expense()
Function
def add_expense():
desc = desc_entry.get()
category = category_entry.get()
amount = amount_entry.get()
Fetches input from the three Entry fields:
desc
,category
, andamount
.
if not desc or not category or not amount:
messagebox.showerror("Input Error", "All fields are required.")
return
Validates that none of the fields are empty. Shows an error message if any are missing.
try:
amount = float(amount)
except ValueError:
messagebox.showerror("Input Error", "Amount must be a number.")
return
Converts the
amount
to a float. If conversion fails (e.g. user types letters), it shows an error.
expenses.append((desc, category, amount))
Adds the new expense to the
expenses
list as a tuple.
update_expense_list()
update_total()
Calls helper functions to update the table and total label.
desc_entry.delete(0, tk.END)
category_entry.delete(0, tk.END)
amount_entry.delete(0, tk.END)
Clears the input fields after successful addition.
5. Define the update_expense_list()
Function
def update_expense_list():
for row in tree.get_children():
tree.delete(row)
First clears any existing rows from the Treeview table.
for i, (desc, category, amount) in enumerate(expenses, start=1):
tree.insert("", "end", values=(i, desc, category, f"${amount:.2f}"))
Re-populates the table with current values in the
expenses
list.Formats the amount to show 2 decimal places.
6. Define the update_total()
Function
def update_total():
total = sum(amount for _, _, amount in expenses)
total_label.config(text=f"Total: ${total:.2f}")
Calculates the sum of all expense amounts.
Updates the total label to show the new total formatted as a dollar amount.
7. Create GUI Input Fields
tk.Label(root, text="Description", bg="white").pack()
desc_entry = tk.Entry(root, width=40)
desc_entry.pack()
Label and entry for the expense description.
tk.Label(root, text="Category", bg="white").pack()
category_entry = tk.Entry(root, width=40)
category_entry.pack()
Label and entry for the category (e.g., Food, Travel).
tk.Label(root, text="Amount ($)", bg="white").pack()
amount_entry = tk.Entry(root, width=40)
amount_entry.pack()
Label and entry for the amount in dollars.
8. Add Button to Trigger Expense Addition
add_btn = tk.Button(root, text="Add Expense", command=add_expense, bg="#4CAF50", fg="white")
add_btn.pack(pady=10)
When clicked, this button runs the
add_expense()
function.
9. Create Treeview Table to Show Expenses
columns = ("#", "Description", "Category", "Amount")
tree = ttk.Treeview(root, columns=columns, show="headings")
for col in columns:
tree.heading(col, text=col)
tree.pack(pady=10, fill="x")
Creates a table with 4 columns:
#
: Serial numberDescription
: Expense nameCategory
: Category typeAmount
: Dollar amount
The
fill="x"
option makes the table stretch across the window width.
10. Display the Total Amount
total_label = tk.Label(root, text="Total: $0.00", font=("Arial", 12, "bold"), bg="white", fg="green")
total_label.pack(pady=10)
This label displays the total expense amount.
Styled with a green font to highlight the summary.
11. Run the GUI Application
root.mainloop()
Starts the Tkinter event loop.
Keeps the application running and responsive to user interaction.
Summary
Part | Purpose |
---|---|
add_expense() | Adds a new expense and validates input |
update_expense_list() | Refreshes the list of expenses in the table |
update_total() | Computes and displays the running total |
Treeview | Displays expenses in a neat tabular format |
Tkinter Entry & Labels | GUI input for description, category, and amount |
source code
import tkinter as tk
from tkinter import ttk, messagebox
root = tk.Tk()
root.title("Expense Tracker")
root.geometry("500x500")
root.config(bg="white")
expenses = []
def add_expense():
desc = desc_entry.get()
category = category_entry.get()
amount = amount_entry.get()
if not desc or not category or not amount:
messagebox.showerror("Input Error", "All fields are required.")
return
try:
amount = float(amount)
except ValueError:
messagebox.showerror("Input Error", "Amount must be a number.")
return
expenses.append((desc, category, amount))
update_expense_list()
update_total()
desc_entry.delete(0, tk.END)
category_entry.delete(0, tk.END)
amount_entry.delete(0, tk.END)
def update_expense_list():
for row in tree.get_children():
tree.delete(row)
for i, (desc, category, amount) in enumerate(expenses, start=1):
tree.insert("", "end", values=(i, desc, category, f"${amount:.2f}"))
def update_total():
total = sum(amount for _, _, amount in expenses)
total_label.config(text=f"Total: ${total:.2f}")
# Input Fields
tk.Label(root, text="Description", bg="white").pack()
desc_entry = tk.Entry(root, width=40)
desc_entry.pack()
tk.Label(root, text="Category", bg="white").pack()
category_entry = tk.Entry(root, width=40)
category_entry.pack()
tk.Label(root, text="Amount ($)", bg="white").pack()
amount_entry = tk.Entry(root, width=40)
amount_entry.pack()
add_btn = tk.Button(root, text="Add Expense", command=add_expense, bg="#4CAF50", fg="white")
add_btn.pack(pady=10)
# Expense Table
columns = ("#", "Description", "Category", "Amount")
tree = ttk.Treeview(root, columns=columns, show="headings")
for col in columns:
tree.heading(col, text=col)
tree.pack(pady=10, fill="x")
# Total
total_label = tk.Label(root, text="Total: $0.00", font=("Arial", 12, "bold"), bg="white", fg="green")
total_label.pack(pady=10)
root.mainloop()
output

