0% found this document useful (0 votes)
31 views6 pages

Finance Dashboard

bvfdchvchvs

Uploaded by

johifij532
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views6 pages

Finance Dashboard

bvfdchvchvs

Uploaded by

johifij532
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

import sys

import csv
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QLineEdit,
QPushButton,
QVBoxLayout, QWidget, QListWidget, QComboBox,
QHBoxLayout,
QFileDialog, QMessageBox, QDateEdit, QSplitter,
QCheckBox)
from PyQt5.QtCore import Qt, QDate
from PyQt5.QtGui import QFont, QFontDatabase
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import locale

class FinanceDashboard(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Finance Dashboard")
self.setGeometry(100, 100, 800, 600)

# Load custom font


font_id = QFontDatabase.addApplicationFont("Roboto-Regular.ttf")
roboto_family = QFontDatabase.applicationFontFamilies(font_id)[0]
self.custom_font = QFont(roboto_family, 10)

self.transactions = []

# Set locale for Indian currency formatting


locale.setlocale(locale.LC_ALL, 'en_IN.UTF-8')

self.init_ui()

def init_ui(self):
self.layout = QHBoxLayout()

# Create a splitter
self.splitter = QSplitter(Qt.Horizontal)

# Left Column for Input Fields


left_layout = QVBoxLayout()
title = QLabel("Finance Dashboard")
title.setFont(QFont(self.custom_font.family(), 24, QFont.Bold))
title.setAlignment(Qt.AlignCenter)
left_layout.addWidget(title)

# Transaction Date
self.date_input = QDateEdit()
self.date_input.setDate(QDate.currentDate())
self.date_input.setFont(self.custom_font)
left_layout.addWidget(self.date_input)

# Transaction Amount
self.amount_input = QLineEdit()
self.amount_input.setPlaceholderText("Amount (e.g., 1000.00)")
self.amount_input.setFont(self.custom_font)
left_layout.addWidget(self.amount_input)

# Transaction Category
self.category_combobox = QComboBox()
self.category_combobox.addItems(["Select Category", "Income", "Expense"])
self.category_combobox.setFont(self.custom_font)
left_layout.addWidget(self.category_combobox)

# Transaction Description
self.description_input = QLineEdit()
self.description_input.setPlaceholderText("Description (e.g., Salary,
Grocery)")
self.description_input.setFont(self.custom_font)
left_layout.addWidget(self.description_input)

# Add Transaction Button


self.add_transaction_button = QPushButton("Add Transaction")
self.add_transaction_button.clicked.connect(self.add_transaction)
self.add_transaction_button.setFont(self.custom_font)
left_layout.addWidget(self.add_transaction_button)

# Transaction List
self.transaction_list = QListWidget()
self.transaction_list.setFont(self.custom_font)
left_layout.addWidget(self.transaction_list)

# Summary Layout
summary_layout = QHBoxLayout()
self.total_income_label = QLabel("Total Income: ₹0.00")
self.total_income_label.setFont(self.custom_font)
summary_layout.addWidget(self.total_income_label)

self.export_button = QPushButton("Export to CSV")


self.export_button.clicked.connect(self.export_to_csv)
self.export_button.setFont(self.custom_font)
summary_layout.addWidget(self.export_button)

self.total_expenses_label = QLabel("Total Expenses: ₹0.00")


self.total_expenses_label.setFont(self.custom_font)
summary_layout.addWidget(self.total_expenses_label)

self.import_button = QPushButton("Import from CSV")


self.import_button.clicked.connect(self.import_from_csv)
self.import_button.setFont(self.custom_font)
summary_layout.addWidget(self.import_button)

self.net_savings_label = QLabel("Net Savings: ₹0.00")


self.net_savings_label.setFont(self.custom_font)
summary_layout.addWidget(self.net_savings_label)

left_layout.addLayout(summary_layout)

# Add left layout to the splitter


left_widget = QWidget()
left_widget.setLayout(left_layout)
self.splitter.addWidget(left_widget)

# Right Column for Visualizations


self.visualization_layout = QVBoxLayout()
self.canvas_income_expenses = FigureCanvas(plt.Figure(figsize=(5, 4))) #
Smaller figure size
self.canvas_category_distribution = FigureCanvas(plt.Figure(figsize=(5,
4))) # Smaller figure size

self.visualization_layout.addWidget(QLabel("Income vs Expenses"))
self.visualization_layout.addWidget(self.canvas_income_expenses)

self.visualization_layout.addWidget(QLabel("Expense Distribution by
Category"))
self.visualization_layout.addWidget(self.canvas_category_distribution)

# Add right layout to the splitter


right_widget = QWidget()
right_widget.setLayout(self.visualization_layout)
self.splitter.addWidget(right_widget)

self.layout.addWidget(self.splitter)

self.central_widget = QWidget()
self.central_widget.setLayout(self.layout)
self.setCentralWidget(self.central_widget)

# Dark Theme Checkbox


self.dark_theme_checkbox = QCheckBox("Enable Dark Theme")
self.dark_theme_checkbox.setFont(self.custom_font)
self.dark_theme_checkbox.stateChanged.connect(self.toggle_theme)
left_layout.addWidget(self.dark_theme_checkbox)

self.apply_light_theme()

def add_transaction(self):
try:
date = self.date_input.date().toString(Qt.ISODate) #"yyyy-MM-dd"
amount = float(self.amount_input.text())
category = self.category_combobox.currentText()
description = self.description_input.text()

if category != "Select Category" and amount >= 0 and description:


self.transactions.append((date, category, description, amount))
self.transaction_list.addItem(f"{date} | {category} | {description}
| ₹{amount:.2f}")
self.amount_input.clear()
self.description_input.clear()
self.category_combobox.setCurrentIndex(0)
self.update_summary()
self.update_visualizations()
else:
QMessageBox.warning(self, "Input Error", "Please fill all fields
and select a category.")
except ValueError:
QMessageBox.warning(self, "Input Error", "Please enter a valid
amount.")

def update_summary(self):
total_income = sum(amount for _, category, _, amount in self.transactions
if category.lower() == "income")
total_expenses = sum(amount for _, category, _, amount in self.transactions
if category.lower() == "expense")
net_savings = total_income - total_expenses

self.total_income_label.setText(f"Total Income: ₹{total_income:.2f}")


self.total_expenses_label.setText(f"Total Expenses: ₹{total_expenses:.2f}")
self.net_savings_label.setText(f"Net Savings: ₹{net_savings:.2f}")

def update_visualizations(self):
if self.transactions:
self.plot_income_vs_expenses()
self.plot_category_distribution()

def plot_income_vs_expenses(self):
income = sum(amount for _, category, _, amount in self.transactions if
category.lower() == "income")
expenses = sum(amount for _, category, _, amount in self.transactions if
category.lower() == "expense")

ax = self.canvas_income_expenses.figure.add_subplot(111)
ax.clear() # Clear the previous plot

ax.bar(["Income", "Expenses"], [income, expenses], color=['green', 'red'])


ax.set_ylabel('Amount (₹)')
ax.set_title('Income vs Expenses')

# Set the background color based on the current theme


if self.dark_theme_checkbox.isChecked():
ax.set_facecolor('#3C3C3C') # Dark background
self.canvas_income_expenses.figure.patch.set_facecolor('#2E2E2E') #
Dark figure background
else:
ax.set_facecolor('white') # Light background
self.canvas_income_expenses.figure.patch.set_facecolor('white') #
Light figure background

# Format y-axis labels for Indian currency style


ax.get_yaxis().set_major_formatter(
plt.FuncFormatter(lambda x, _: f'₹{locale.format_string("%d", x,
grouping=True)}'))

self.canvas_income_expenses.draw()

def plot_category_distribution(self):
# Prepare data for individual expenses in the pie chart
expense_labels = [f"{description} ({category}) - ₹{amount:.2f}" for _,
category, description, amount in
self.transactions if category.lower() == "expense"]
expense_values = [amount for _, category, _, amount in self.transactions if
category.lower() == "expense"]

ax = self.canvas_category_distribution.figure.add_subplot(111)
ax.clear() # Clear the previous plot

ax.pie(expense_values, labels=expense_labels, autopct='%1.1f%%',


startangle=140, colors=plt.cm.tab20.colors)
ax.axis('equal') # Ensures the pie is drawn as a circle.
ax.set_title("Detailed Expense Distribution")

# Set background color based on current theme


if self.dark_theme_checkbox.isChecked():
ax.set_facecolor('#3C3C3C')
self.canvas_category_distribution.figure.patch.set_facecolor('#2E2E2E')
else:
ax.set_facecolor('white')
self.canvas_category_distribution.figure.patch.set_facecolor('white')

self.canvas_category_distribution.draw()

def export_to_csv(self):
path, _ = QFileDialog.getSaveFileName(self, "Export Transactions", "", "CSV
Files (*.csv)")
if path:
with open(path, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(["Date", "Category", "Description", "Amount"])
writer.writerows(self.transactions)
QMessageBox.information(self, "Export Successful", "Transactions
exported successfully!")

def import_from_csv(self):
path, _ = QFileDialog.getOpenFileName(self, "Import Transactions", "", "CSV
Files (*.csv)")
if path:
with open(path, 'r', newline='') as file:
reader = csv.reader(file)
next(reader) # Skip header
for row in reader:
try:
date, category, description, amount = row
amount = float(amount)
self.transactions.append((date, category, description,
amount))
self.transaction_list.addItem(f"{date} | {category} |
{description} | ₹{amount:.2f}")
except ValueError:
continue # Skip rows with invalid data
self.update_summary()
self.update_visualizations()

def toggle_theme(self, state):


if state == Qt.Checked:
self.apply_dark_theme()
else:
self.apply_light_theme()

def apply_dark_theme(self):
self.setStyleSheet("background-color: #2E2E2E; color: white;")
for widget in self.findChildren(QWidget):
widget.setStyleSheet("background-color: #2E2E2E; color: white;")
if isinstance(widget, QLineEdit):
widget.setStyleSheet("background-color: #3C3C3C; color: white;")
elif isinstance(widget, QPushButton):
widget.setStyleSheet("background-color: #4A4A4A; color: white;")
self.update_visualizations() # Update visualizations to reflect the new
theme

def apply_light_theme(self):
self.setStyleSheet("background-color: white; color: black;")
for widget in self.findChildren(QWidget):
widget.setStyleSheet("background-color: white; color: black;")
if isinstance(widget, QLineEdit):
widget.setStyleSheet("background-color: #E0E0E0; color: black;")
elif isinstance(widget, QPushButton):
widget.setStyleSheet("background-color: #E0E0E0; color: black;")
self.update_visualizations() # Update visualizations to reflect the new
theme

if __name__ == "__main__":
app = QApplication(sys.argv)
window = FinanceDashboard()
window.show()
sys.exit(app.exec_())

You might also like