ProyectoFinalPython/app/main.py

169 lines
6.4 KiB
Python

import tkinter as tk
from tkinter import Menu
from tkinter import ttk
import threading
from app.chat_server.Server import Server
from app.widgets import ClockLabel
from app.ConfigMgr import ConfigMgr
from app.widgets.ChatTab import ChatTab
from app.widgets.MusicDownloadTab import MusicDownloadTab
from app.widgets.MusicPlayerTab import MusicPlayerTab
from app.widgets.TodoTab import TodoTab
from app.widgets.UsageLabels import CPULabel, RAMLabel, BatteryLabel, NetworkLabel
from app.widgets.WeatherTab import WeatherTab
stop_event = threading.Event()
def on_closing():
# Kill all threads that are linked to the stop_event
# This ensures that execution is thread-safe
stop_event.set()
# Close the main window
root.quit()
root.destroy()
def on_config_changed():
chat_frame.change_server_url(config_manager.config["Chat"]["server"])
chat_frame.change_sender_name(config_manager.config["Chat"]["name"])
weather_tab.changeCity(config_manager.config["Weather"]["city"])
# Create the main window
root = tk.Tk()
root.title("Responsive Window")
root.geometry("1150x700")
config_manager = ConfigMgr(root, config_changed_listener=on_config_changed)
server = Server(host="localhost", port=2020, stop_event=stop_event)
# Configure the main window to be responsive
root.columnconfigure(0, weight=0)
root.columnconfigure(1, weight=1)
root.columnconfigure(2, weight=0)
root.rowconfigure(0, weight=1)
root.rowconfigure(1, weight=0)
# Create the top menu
menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_command(label="Open")
file_menu.add_separator()
file_menu.add_command(label="Config", command=config_manager.display_config_window)
file_menu.add_command(label="Exit", command=on_closing)
edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label="Copy")
edit_menu.add_command(label="Paste")
menu_bar.add_cascade(label="File", menu=file_menu)
menu_bar.add_cascade(label="Edit", menu=edit_menu)
root.config(menu=menu_bar)
# Create the side and central frames
frame_left = tk.Frame(root, bg="lightblue", width=300)
frame_center = tk.Frame(root, bg="white")
frame_right = tk.Frame(root, bg="lightgreen", width=300)
# Place the side and central frames
frame_left.grid(row=0, column=0, sticky="ns")
frame_center.grid(row=0, column=1, sticky="nsew")
frame_right.grid(row=0, column=2, sticky="ns")
# Configure the fixed sizes of the side frames
frame_left.grid_propagate(False)
frame_right.grid_propagate(False)
# Configure the left frame to have three rows
frame_left.rowconfigure(0, weight=1)
frame_left.rowconfigure(1, weight=0)
frame_left.rowconfigure(2, weight=0)
# Add weather tab to the left frame, occupying 1/3 of the height
weather_tab = WeatherTab(frame_left, stop_event=stop_event,
city=config_manager.config["Weather"]["city"], refresh_rate=300)
weather_tab.grid(row=0, column=0, sticky="nsew")
# Adjust the remaining rows to occupy the rest of the space
frame_left.rowconfigure(1, weight=2)
frame_left.rowconfigure(2, weight=2)
# Divide the central frame into two parts (top variable and bottom fixed)
frame_center.rowconfigure(0, weight=1)
frame_center.rowconfigure(1, weight=0)
frame_center.columnconfigure(0, weight=1)
# Create subframes within the central frame
frame_top = tk.Frame(frame_center, bg="lightyellow")
frame_bottom = tk.Frame(frame_center, bg="lightgray", height=100)
# Place the subframes within the central frame
frame_top.grid(row=0, column=0, sticky="nsew")
frame_bottom.grid(row=1, column=0, sticky="ew")
# Fix the size of the bottom part
frame_bottom.grid_propagate(False)
# Create the status bar
status_bar = tk.Label(root, text="Status bar", bg="lightgray", anchor="w")
status_bar.grid(row=1, column=0, columnspan=3, sticky="ew")
# Notebook for widgets
style = ttk.Style()
style.configure("CustomNotebook.TNotebook.Tab", font=("Arial", 12, "bold"))
notebook = ttk.Notebook(frame_top, style="CustomNotebook.TNotebook")
notebook.pack(fill="both", expand=True)
# Add the tabs to the notebook
music_download_tab = MusicDownloadTab(notebook, stop_event=stop_event)
music_download_tab.pack(fill="both", expand=True)
notebook.add(music_download_tab, text="Music Download")
# Add the TodoTab to the notebook
todo_tab = TodoTab(notebook, stop_event=stop_event)
todo_tab.pack(fill="both", expand=True)
notebook.add(todo_tab, text="Todo List")
# Create the chat and music player frames within the right frame
frame_chat = tk.Frame(frame_right, bg="lightgreen")
frame_music_player = tk.Frame(frame_right)
# Place the chat and music player frames within the right frame
frame_chat.grid(row=0, column=0, sticky="nsew")
frame_music_player.grid(row=1, column=0, sticky="nsew")
# Configure the right frame to be responsive
frame_right.rowconfigure(0, weight=3)
frame_right.rowconfigure(1, weight=1)
frame_right.columnconfigure(0, weight=1)
# Create and place the chat frame and music player tab
chat_frame = ChatTab(frame_chat, chat_server_url=config_manager.config["Chat"]["server"],
sender_name=config_manager.config["Chat"]["name"],
stop_event=stop_event, width=200, bg="lightgreen", refresh_rate=1)
chat_frame.pack(fill="both", expand=True)
music_player = MusicPlayerTab(frame_music_player, stop_event=stop_event, refresh_rate=5)
music_player.pack(fill="both", expand=True)
label_cpu = CPULabel(status_bar, bg="lightgreen", font=("Helvetica", 10), relief="groove", anchor="center", width=10, stop_event=stop_event, refresh_rate=1)
label_ram = RAMLabel(status_bar, bg="lightcoral", font=("Helvetica", 10), relief="groove", anchor="center", width=10, stop_event=stop_event, refresh_rate=3)
label_battery = BatteryLabel(status_bar, bg="lightblue", font=("Helvetica", 10), relief="groove", anchor="center", width=20, stop_event=stop_event, refresh_rate=10)
label_net = NetworkLabel(status_bar, text="Network", bg="lightpink", font=("Helvetica", 10), relief="groove", anchor="center", width=20, stop_event=stop_event, refresh_rate=5)
label_time = ClockLabel(status_bar, font=("Helvetica", 12), bd=1, fg="darkblue", relief="sunken", anchor="center", width=20, stop_event=stop_event, refresh_rate=0.5)
label_cpu.pack(side="left", fill="both", expand=True)
label_ram.pack(side="left", fill="both", expand=True)
label_battery.pack(side="left", fill="both", expand=True)
label_net.pack(side="left", fill="both", expand=True)
label_time.pack(side="right", fill="both", expand=True)
root.protocol("WM_DELETE_WINDOW", on_closing)
# Run the application
root.mainloop()