Byg denne enkle app til at øve din matematikprogrammering og lære lidt om GUI-kodning undervejs.
En udgiftsmåler er et vigtigt værktøj, der hjælper enkeltpersoner og virksomheder med at administrere deres finansielle transaktioner. Med en udgiftsmåler kan du oprette budgetter, kategorisere udgifter og analysere forbrugsmønstre.
Find ud af, hvordan du bygger en udgiftsporingsapp med en grænseflade på tværs af platforme i Python.
Tkinter-, CSV- og Matplotlib-modulerne
For at bygge denne udgiftstracker skal du bruge modulerne Tkinter, CSV og Matplotlib.
Tkinter lader dig oprette desktop-applikationer. Den tilbyder en række widgets som knapper, etiketter og tekstbokse, der gør det nemt at udvikle apps.
CSV-modulet er et indbygget Python-bibliotek, der giver funktionalitet til læsning og skrivning CSV-filer (Comma-Separated Values)..
Med Matplotlib kan du bygge interaktive visualiseringer såsom grafer, plots og diagrammer. Brug af det med moduler som OpenCV kan hjælpe dig mestre billedforbedringsteknikker også.
For at installere disse moduler skal du køre:
pip install tk matplotlib
Definer strukturen af Expense Tracker-appen
Du kan finde dette projekts kildekode i dens GitHub-depot.
Begynd med at importere de nødvendige moduler. Definer en klasse, ExpenseTrackerApp. Indstil titlen og dimensionerne. Definer en liste til at gemme udgifterne og en anden for kategorierne. Initialiser a StringVar som hedder kategori_var og indstil dens startværdi til den første kategori i kategorilisten. Afslut ved at ringe til oprette_widgets metode.
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import csv
import matplotlib.pyplot as plt
classExpenseTrackerApp(tk.Tk):
def__init__(self):
super().__init__()
self.title("Expense Tracker")
self.geometry("1300x600")
self.expenses = []
self.categories = [
"Food",
"Transportation",
"Utilities",
"Entertainment",
"Other",
]
self.category_var = tk.StringVar(self)
self.category_var.set(self.categories[0])
self.create_widgets()
Det oprette_widgets metoden er ansvarlig for at tilføje UI-komponenter til din app. Opret en ramme for udgiftspostens etiketter og poster. Opret seks etiketter: en hver for overskrift, udgiftsbeløb, varebeskrivelse, kategori, dato og samlet udgift. Indstil hver enkelts overordnede element, den tekst, den skal vise, og dens skrifttype.
Opret tre indgangswidgets og en Kombinationsfelt for at få det tilsvarende input. For indgangswidgets skal du indstille det overordnede element, skrifttypestilen og bredden. Definer det overordnede element, listen over værdier, skrifttypestilen og bredden for Kombinationsfelt. Binde kategori_var til den, så den valgte værdi opdateres automatisk.
defcreate_widgets(self):
self.label = tk.Label(
self, text="Expense Tracker", font=("Helvetica", 20, "bold")
)
self.label.pack(pady=10)
self.frame_input = tk.Frame(self)
self.frame_input.pack(pady=10)
self.expense_label = tk.Label(
self.frame_input, text="Expense Amount:", font=("Helvetica", 12)
)
self.expense_label.grid(row=0, column=0, padx=5)
self.expense_entry = tk.Entry(
self.frame_input, font=("Helvetica", 12), width=15
)
self.expense_entry.grid(row=0, column=1, padx=5)
self.item_label = tk.Label(
self.frame_input, text="Item Description:", font=("Helvetica", 12)
)
self.item_label.grid(row=0, column=2, padx=5)
self.item_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=20)
self.item_entry.grid(row=0, column=3, padx=5)
self.category_label = tk.Label(
self.frame_input, text="Category:", font=("Helvetica", 12)
)
self.category_label.grid(row=0, column=4, padx=5)
self.category_dropdown = ttk.Combobox(
self.frame_input,
textvariable=self.category_var,
values=self.categories,
font=("Helvetica", 12),
width=15,
)
self.category_dropdown.grid(row=0, column=5, padx=5)
self.date_label = tk.Label(
self.frame_input, text="Date (YYYY-MM-DD):", font=("Helvetica", 12)
)
self.date_label.grid(row=0, column=6, padx=5)
self.date_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=15)
self.date_entry.grid(row=0, column=7, padx=5)
Definer fem knapper: Tilføj udgift, Rediger udgift, Slet udgift, Spar udgifter, og Vis udgiftsdiagram. Indstil det overordnede element for hver, den tekst, den skal vise, og den kommando, den vil køre, når du klikker på den. Opret en ramme til listeboksen. Indstil det overordnede element, skrifttypestilen og bredden.
Opret en lodret rullepanel og placer den på højre side af rammen. Brug den til at rulle gennem indholdet af listeboksen. Organiser alle elementerne med den nødvendige polstring og kald update_total_label().
self.add_button = tk.Button(self, text="Add Expense", command=self.add_expense)
self.add_button.pack(pady=5)
self.frame_list = tk.Frame(self)
self.frame_list.pack(pady=10)
self.scrollbar = tk.Scrollbar(self.frame_list)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.expense_listbox = tk.Listbox(
self.frame_list,
font=("Helvetica", 12),
width=70,
yscrollcommand=self.scrollbar.set,
)
self.expense_listbox.pack(pady=5)
self.scrollbar.config(command=self.expense_listbox.yview)
self.edit_button = tk.Button(
self, text="Edit Expense", command=self.edit_expense
)
self.edit_button.pack(pady=5)
self.delete_button = tk.Button(
self, text="Delete Expense", command=self.delete_expense
)
self.delete_button.pack(pady=5)
self.save_button = tk.Button(
self, text="Save Expenses", command=self.save_expenses
)
self.save_button.pack(pady=5)
self.total_label = tk.Label(
self, text="Total Expenses:", font=("Helvetica", 12)
)
self.total_label.pack(pady=5)
self.show_chart_button = tk.Button(
self, text="Show Expenses Chart", command=self.show_expenses_chart
)
self.show_chart_button.pack(pady=5)
self.update_total_label()
Definer funktionaliteten af Expense Tracker
Definer en metode, tilføje_udgift. Hent værdien af udgiften, varen, kategorien og datoen. Hvis værdien af udgiften og datoen er gyldige, lægges udgiften til udgifter liste. Indsæt denne post i listeboksen og formater den korrekt. Når det er indsat, skal du slette brugerinput i indtastningsfelterne for nyt input.
Ellers skal du vise en advarsel om, at værdierne for udgift og dato ikke må være tomme. Opkald update_total_label.
defadd_expense(self):
expense = self.expense_entry.get()
item = self.item_entry.get()
category = self.category_var.get()
date = self.date_entry.get()
if expense and date:
self.expenses.append((expense, item, category, date))
self.expense_listbox.insert(
tk.END, f"{expense} - {item} - {category} ({date})"
)
self.expense_entry.delete(0, tk.END)
self.item_entry.delete(0, tk.END)
self.date_entry.delete(0, tk.END)
else:
messagebox.showwarning("Warning", "Expense and Date cannot be empty.")
self.update_total_label()
Definer en metode, edit_expense. Hent indekset for den valgte post og få udgiften. Åbn en dialogboks, hvor du bliver bedt om at indtaste udgiften. Hvis brugeren har angivet en ny udgift, skal udgiftslisten ændres i overensstemmelse hermed. Ring til refresh_list og update_total_label.
defedit_expense(self):
selected_index = self.expense_listbox.curselection()
if selected_index:
selected_index = selected_index[0]
selected_expense = self.expenses[selected_index]
new_expense = simpledialog.askstring(
"Edit Expense", "Enter new expense:", initialvalue=selected_expense[0]
)
if new_expense:
self.expenses[selected_index] = (
new_expense,
selected_expense[1],
selected_expense[2],
selected_expense[3],
)
self.refresh_list()
self.update_total_label()
Definer en metode, slette_udgift. Hent indekset for den valgte post og få udgiften. Send indekset for den post, du vil slette. Slet denne post fra listeboksen, og ring til update_total_label.
defdelete_expense(self):
selected_index = self.expense_listbox.curselection()
if selected_index:
selected_index = selected_index[0]
del self.expenses[selected_index]
self.expense_listbox.delete(selected_index)
self.update_total_label()
Definer en metode, refresh_list. Slet den eksisterende post, og tilføj i stedet en ny post med de opdaterede værdier.
defrefresh_list(self):
self.expense_listbox.delete(0, tk.END)
for expense, item, category, date in self.expenses:
self.expense_listbox.insert(
tk.END, f"{expense} - {item} - {category} ({date})"
)
Definer en metode, update_total_label. Beregn summen af alle udgifter på listen og opdater den på etiketten. Definer en anden metode, spare_udgifter. Opret og åbn en CSV fil navngivet udgifter.csv i skrivetilstand. Tilføj kolonneoverskrifter til CSV-filen som den første række. Gentag over hver udgiftspost, og skriv den som en række.
defupdate_total_label(self):
total_expenses = sum(float(expense[0]) for expense in self.expenses)
self.total_label.config(text=f"Total Expenses: USD {total_expenses:.2f}")
defsave_expenses(self):
with open("expenses.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
column_headers = ["Expense Amount", "Item Description", "Category", "Date"]
writer.writerow(column_headers)
for expense in self.expenses:
writer.writerow(expense))
Definer en metode, vis_udgifter_diagram. Definer en ordbog, kategori_totaler. Gentag gennem udgifter liste og konverter udgiftsbeløbet til flydende. Gem det samlede udgiftsbeløb for hver kategori. Hvis kategorien allerede findes i ordbogen, øges totalen med det aktuelle udgiftsbeløb. Ellers skal du oprette en ny post med det aktuelle udgiftsbeløb.
defshow_expenses_chart(self):
category_totals = {}
for expense, _, category, _ in self.expenses:
try:
amount = float(expense)
except ValueError:
continue
category_totals[category] = category_totals.get(category, 0) + amount
Udtræk kategorierne og udgifterne i to forskellige lister. Opret en ny figur til plottet med den angivne størrelse. Generer et cirkeldiagram, brug udgiftslisten som data og kategorilisten som etiket. Det autopkt parameter angiver formatet til visning af procentværdierne på diagramudsnittene. Passere lige til plt.akse for at sikre, at du tegner cirkeldiagrammet som en cirkel. Indstil titlen på cirkeldiagrammet og vis det.
categories = list(category_totals.keys())
expenses = list(category_totals.values())
plt.figure(figsize=(8, 6))
plt.pie(
expenses, labels=categories, autopct="%1.1f%%", startangle=140, shadow=True
)
plt.axis("equal")
plt.title(f"Expense Categories Distribution (USD)")
plt.show()
Opret en instans af ExpenseTrackerApp klasse. Det mainloop() funktion fortæller Python at køre Tkinter-hændelsesløkken og lytte efter hændelser, indtil du lukker vinduet.
if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()
Test forskellige funktioner i Python Expense Tracker
Når du kører programmet, åbner det et programvindue. Dette har inputfelter til at registrere udgiften, varebeskrivelsen, kategorien og datoen. Indtast nogle data, og klik på Tilføj udgift knap; du vil se, at posten bliver tilføjet til listeboksen. Programmet opdaterer også de samlede udgifter.
Vælg en post, og klik på Rediger udgifter knap. En dialogboks vises, hvor du kan opdatere den individuelle post.
Ved at klikke på Slet udgifter knappen for at fjerne den valgte post.
Ved at ramme Vis udgiftsdiagram knappen, viser programmet et cirkeldiagram. Cirkeldiagrammet viser udgiften for hver kategori sammen med dens navn og procent.
Forbedring af Expense Tracker
Du kan tilføje søgefunktionalitet for at lade brugere finde specifikke udgifter baseret på deres beskrivelse, beløb, kategori eller dato. Du kan tilføje en mulighed for at sortere og filtrere poster. Lokaliser appen til at understøtte forskellige sprog og valutaformater.
Du kan også udvide appen med understøttelse af notifikationer. Lad brugeren opsætte advarsler for at forhindre dem i at overskride budgetgrænser eller fremhæve usædvanlige udgifter.