Files
Finance-Control/app/ui/main_window.py

123 lines
4.3 KiB
Python

import customtkinter as ctk
from app.config import APP_TITLE, MIN_HEIGHT, MIN_WIDTH, WINDOW_SIZE
from app.ui.accounts_frame import AccountsFrame
from app.ui.budgets_frame import BudgetsFrame
from app.ui.categories_frame import CategoriesFrame
from app.ui.dashboard_frame import DashboardFrame
from app.ui.reports_frame import ReportsFrame
from app.ui.subscriptions_frame import SubscriptionsFrame
from app.ui.transactions_frame import TransactionsFrame
class FinanceApp(ctk.CTk):
def __init__(self) -> None:
super().__init__()
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
self.title(APP_TITLE)
self.geometry(WINDOW_SIZE)
self.minsize(MIN_WIDTH, MIN_HEIGHT)
self.grid_columnconfigure(1, weight=1)
self.grid_rowconfigure(0, weight=1)
self.sidebar = ctk.CTkFrame(self, width=240, corner_radius=0)
self.sidebar.grid(row=0, column=0, sticky="nsew")
self.sidebar.grid_rowconfigure(9, weight=1)
self.content = ctk.CTkFrame(self, fg_color="transparent")
self.content.grid(row=0, column=1, sticky="nsew", padx=16, pady=16)
self.content.grid_rowconfigure(0, weight=1)
self.content.grid_columnconfigure(0, weight=1)
self._build_sidebar()
self._build_frames()
self.show_frame("Главная")
self.refresh_all()
def _build_sidebar(self) -> None:
title_label = ctk.CTkLabel(
self.sidebar,
text="Finance Control",
font=ctk.CTkFont(size=24, weight="bold"),
)
title_label.grid(row=0, column=0, padx=20, pady=(24, 8), sticky="w")
subtitle_label = ctk.CTkLabel(
self.sidebar,
text="курсовой проект",
text_color="gray70",
)
subtitle_label.grid(row=1, column=0, padx=20, pady=(0, 16), sticky="w")
pages = [
"Главная",
"Счета",
"Категории",
"Операции",
"Подписки",
"Бюджеты",
"Отчёты",
]
for index, page_name in enumerate(pages, start=2):
button = ctk.CTkButton(
self.sidebar,
text=page_name,
height=42,
anchor="w",
command=lambda name=page_name: self.show_frame(name),
)
button.grid(row=index, column=0, padx=20, pady=6, sticky="ew")
theme_label = ctk.CTkLabel(
self.sidebar,
text="Тема",
text_color="gray70",
)
theme_label.grid(row=10, column=0, padx=20, pady=(12, 6), sticky="w")
self.theme_menu = ctk.CTkOptionMenu(
self.sidebar,
values=["Тёмная", "Светлая", "Системная"],
command=self.change_theme,
)
self.theme_menu.set("Тёмная")
self.theme_menu.grid(row=11, column=0, padx=20, pady=(0, 20), sticky="ew")
def _build_frames(self) -> None:
self.frames = {
"Главная": DashboardFrame(self.content, self.refresh_all),
"Счета": AccountsFrame(self.content, self.refresh_all),
"Категории": CategoriesFrame(self.content, self.refresh_all),
"Операции": TransactionsFrame(self.content, self.refresh_all),
"Подписки": SubscriptionsFrame(self.content, self.refresh_all),
"Бюджеты": BudgetsFrame(self.content, self.refresh_all),
"Отчёты": ReportsFrame(self.content, self.refresh_all),
}
for frame in self.frames.values():
frame.grid(row=0, column=0, sticky="nsew")
def show_frame(self, name: str) -> None:
frame = self.frames[name]
if hasattr(frame, "refresh_data"):
frame.refresh_data()
frame.tkraise()
def refresh_all(self) -> None:
for frame in self.frames.values():
if hasattr(frame, "refresh_data"):
frame.refresh_data()
@staticmethod
def change_theme(theme_name: str) -> None:
theme_map = {
"Тёмная": "dark",
"Светлая": "light",
"Системная": "system",
}
ctk.set_appearance_mode(theme_map[theme_name])