323 lines
13 KiB
Python
323 lines
13 KiB
Python
import tkinter as tk
|
|
|
|
import customtkinter as ctk
|
|
|
|
from src.services.processes_manager import ProcessManager
|
|
from src.services.system_monitor import SystemMonitor
|
|
from src.services.tetris_game import TetrisGame
|
|
from src.services.threads_manager import ThreadsManager
|
|
from src.services.email_client import EmailClient
|
|
|
|
|
|
class CenteredWindow(ctk.CTk):
|
|
def __init__(self, title="MultiApp", width_percentage=0.8, height_percentage=0.8):
|
|
# Inicializacion de la clase:
|
|
super().__init__()
|
|
self.title(title)
|
|
self.after_tasks = []
|
|
|
|
#Configurar Email Client
|
|
self.email_client = EmailClient(
|
|
imap_server="192.168.120.103",
|
|
smtp_server="192.168.120.103",
|
|
email="dennis@psp.ieslamar.org",
|
|
password="1234"
|
|
)
|
|
# Inicializar managers (orden es importante)
|
|
self.thread_manager = ThreadsManager(self, self.email_client)
|
|
self.process_manager = ProcessManager()
|
|
self.system_monitor = None
|
|
|
|
# Obtener la resolucion de la pantalla:
|
|
screen_width = self.winfo_screenwidth()
|
|
screen_height = self.winfo_screenheight()
|
|
|
|
# Calcula el tamaño de la ventana según procentaje de la pantalla:
|
|
window_width = int(screen_width * width_percentage)
|
|
window_height = int(screen_height * height_percentage)
|
|
|
|
# Calcular la posicion para centrar la ventana:
|
|
position_x = (screen_width - window_width) // 2
|
|
position_y = (screen_height - window_height) // 2
|
|
|
|
self.geometry(f"{window_width}x{window_height}+{position_x}+{position_y}")
|
|
|
|
#Configura la ventana
|
|
self.configure_window()
|
|
|
|
self.protocol("WM_DELETE_WINDOW", self.on_close)
|
|
|
|
def schedule_tasks(self, delay, callback):
|
|
task_id = self.after(delay, callback)
|
|
self.after_tasks.append(task_id)
|
|
return task_id
|
|
|
|
def configure_window(self):
|
|
# Configuración de la ventana:
|
|
self.configure(bg_color="lightgray")
|
|
self.create_left_panel()
|
|
self.create_right_panel()
|
|
self.create_center_panel()
|
|
self.create_bottom_bar()
|
|
|
|
self.thread_manager.start_threads()
|
|
|
|
|
|
def on_close(self):
|
|
"""Maneja el cierre de la ventana"""
|
|
self.thread_manager.stop_threads()
|
|
|
|
if hasattr(self, "tetris_game") and self.tetris_game.running:
|
|
self.tetris_game.stop_game()
|
|
|
|
if "tetris_game" in self.thread_manager.tasks:
|
|
self.thread_manager.tasks["tetris_game"].stop()
|
|
|
|
if hasattr(self.thread_manager, "scrapper"):
|
|
self.thread_manager.scrapper.stop_scraping()
|
|
|
|
if self.system_monitor:
|
|
self.system_monitor.running = False
|
|
|
|
for task in self.after_tasks:
|
|
self.after_cancel(task)
|
|
|
|
self.destroy()
|
|
|
|
def create_left_panel(self):
|
|
# Panel izquierdo
|
|
left_panel = ctk.CTkFrame(self, width=200)
|
|
left_panel.pack(side=ctk.LEFT, fill=ctk.Y, padx=10, pady=10)
|
|
# Secciones y botones
|
|
sections = {
|
|
"Aplicaciones": [
|
|
("Abrir Chrome", lambda: self.process_manager.open_resource("browser", "https://google.com", "Cannot open browser")),
|
|
("Visual Studio Code", lambda: self.process_manager.open_resource("program", r"C:\Program Files\Microsoft VS Code\Code.exe", "Can't find VSCode")),
|
|
("Explorador de Windows", lambda: self.process_manager.open_resource("program", "explorer.exe", "Can't open Windows Explorer")),
|
|
("Notepad++", lambda: self.process_manager.open_resource("program", r"C:\Program Files\Notepad++\notepad++.exe", "Can't open Notepad++"))
|
|
]
|
|
}
|
|
|
|
url_label = ctk.CTkLabel(left_panel, text="Abrir URL en Chrome", font=("Arial", 12, "bold"))
|
|
url_label.pack(anchor=ctk.W, pady=5, padx=10)
|
|
url_entry_chrome = ctk.CTkEntry(left_panel, placeholder_text="Introduce la URL para navegar")
|
|
url_entry_chrome.pack(pady=5, padx=10)
|
|
|
|
# Botón para abrir la URL ingresada
|
|
internet_access_button = ctk.CTkButton(
|
|
left_panel,
|
|
text="Buscar URL",
|
|
command=lambda: self.process_manager.open_resource("browser", url_entry_chrome.get(), "Cannot open browser")
|
|
)
|
|
internet_access_button.pack(pady=5, padx=10)
|
|
|
|
for section, buttons in sections.items():
|
|
if section:
|
|
section_label = ctk.CTkLabel(left_panel, text=section, font=("Arial", 12, "bold"))
|
|
section_label.pack(anchor=ctk.W, pady=5, padx=10)
|
|
|
|
for text, command in buttons:
|
|
btn = ctk.CTkButton(left_panel, text=text, command=command, width=150)
|
|
btn.pack(pady=5, padx=10)
|
|
|
|
scrapping_label = ctk.CTkLabel(left_panel, text="Scrapping", font=("Arial", 12, "bold"))
|
|
scrapping_label.pack(anchor=ctk.W, pady=5, padx=10)
|
|
url_entry = ctk.CTkEntry(left_panel, placeholder_text="Introduce la URL para scrapear")
|
|
url_entry.pack(pady=5, padx=10)
|
|
|
|
self.left_panel = left_panel
|
|
self.left_panel.url_entry = url_entry
|
|
self.left_panel.url_entry_chrome = url_entry_chrome
|
|
start_button = ctk.CTkButton(left_panel, text="Iniciar Scrapping", command=self.thread_manager.scrapper.start_scraping)
|
|
start_button.pack(pady=5, padx=10)
|
|
|
|
stop_button = ctk.CTkButton(left_panel, text="Detener Scrapping", command=self.thread_manager.scrapper.stop_scraping)
|
|
stop_button.pack(pady=5, padx=10)
|
|
|
|
|
|
|
|
def create_center_panel(self):
|
|
# Panel central con pestañas
|
|
center_panel = ctk.CTkFrame(self)
|
|
center_panel.pack(side=ctk.TOP, fill=ctk.BOTH, expand=True, padx=(10, 10), pady=10)
|
|
|
|
tab_view = ctk.CTkTabview(center_panel, width=500, height=500)
|
|
tab_view.pack(fill=ctk.BOTH, expand=True)
|
|
|
|
# Crear pestañas y manejar contenido por separado
|
|
for tab_name in ["Scrapping", "Radio", "Correos", "Juego", "Sistema"]:
|
|
tab = tab_view.add(tab_name)
|
|
|
|
if tab_name == "Radio":
|
|
self.create_radio_tab(tab)
|
|
|
|
if tab_name == "Scrapping":
|
|
text_widget = ctk.CTkTextbox(tab, width=500, height=400)
|
|
text_widget.pack(fill=ctk.BOTH, expand=True, padx=10, pady=10)
|
|
|
|
text_widget.configure(state="disabled")
|
|
|
|
self.tabs = {"Scrapping": {"text_widget": text_widget}}
|
|
|
|
if tab_name == "Sistema":
|
|
# Crear un frame para los gráficos del sistema
|
|
system_frame = ctk.CTkFrame(tab)
|
|
system_frame.pack(fill=ctk.BOTH, expand=True, padx=5, pady=5)
|
|
|
|
# Inicializar SystemMonitor con el frame de la pestaña
|
|
self.system_monitor = SystemMonitor(system_frame)
|
|
|
|
# Asignar el system_monitor al thread_manager
|
|
self.thread_manager.set_system_monitor(self.system_monitor)
|
|
|
|
elif tab_name == "Juego":
|
|
# Crear un marco intermedio para centrar
|
|
game_frame = ctk.CTkFrame(tab)
|
|
game_frame.pack(expand=True)
|
|
|
|
# Botones para el juego
|
|
button_frame = ctk.CTkFrame(game_frame)
|
|
button_frame.pack(pady=10)
|
|
|
|
start_button = ctk.CTkButton(button_frame, text="Start Game", command=self.start_tetris_game)
|
|
start_button.pack(side=tk.LEFT, padx=5)
|
|
|
|
pause_button = ctk.CTkButton(button_frame, text="Pause Game", command=self.pause_tetris_game)
|
|
pause_button.pack(side=tk.LEFT, padx=5)
|
|
|
|
restart_button = ctk.CTkButton(button_frame, text="Restart Game", command=self.restart_tetris_game)
|
|
restart_button.pack(side=tk.LEFT, padx=5)
|
|
|
|
# Agregar el Tetris dentro de un contenedor
|
|
self.tetris_game = TetrisGame(game_frame)
|
|
self.tetris_game.pack()
|
|
|
|
# else:
|
|
# Agregar contenido genérico a otras pestañas
|
|
#label = ctk.CTkLabel(tab, text=f"Contenido de {tab_name}", font=("Arial", 12))
|
|
#label.pack(pady=10)
|
|
|
|
|
|
|
|
def start_tetris_game(self):
|
|
"""Método para iniciar el juego."""
|
|
if not self.tetris_game.running:
|
|
self.tetris_game.running = True
|
|
#self.tetris_game.update_game()
|
|
|
|
|
|
|
|
def pause_tetris_game(self):
|
|
"""Método para pausar el juego."""
|
|
self.tetris_game.running = False
|
|
|
|
|
|
|
|
def restart_tetris_game(self):
|
|
"""Método para reiniciar el juego."""
|
|
self.tetris_game.reset_game()
|
|
|
|
|
|
|
|
def create_right_panel(self):
|
|
# Panel derecho
|
|
right_panel = ctk.CTkFrame(self, width=250)
|
|
right_panel.pack(side=ctk.RIGHT, fill=ctk.Y, padx=10, pady=10)
|
|
|
|
# Chat
|
|
chat_label = ctk.CTkLabel(right_panel, text="Chat", font=("Arial", 14, "bold"), text_color="red")
|
|
chat_label.pack(anchor=ctk.W, pady=5, padx=10)
|
|
|
|
chat_box = ctk.CTkTextbox(right_panel, height=100)
|
|
chat_box.pack(fill=ctk.X, padx=10, pady=5)
|
|
|
|
send_button = ctk.CTkButton(right_panel, text="Enviar", command=self.dummy_action)
|
|
send_button.pack(pady=5, padx=10)
|
|
|
|
# Lista de alumnos
|
|
for i in range(1, 4):
|
|
student_label = ctk.CTkLabel(right_panel, text=f"Alumno {i}", font=("Arial", 12, "bold"), text_color="black")
|
|
student_label.pack(anchor=ctk.W, pady=5, padx=10)
|
|
|
|
student_info = ctk.CTkLabel(
|
|
right_panel,
|
|
text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
wraplength=200,
|
|
justify="left",
|
|
)
|
|
student_info.pack(anchor=ctk.W, padx=10)
|
|
|
|
|
|
|
|
def create_bottom_bar(self):
|
|
# Crear la barra inferior
|
|
self.bottom_bar = ctk.CTkFrame(self, fg_color="lightblue", height=40)
|
|
self.bottom_bar.pack(side=ctk.BOTTOM, fill=ctk.X, padx=0, pady=0)
|
|
|
|
# Diccionario para las etiquetas dinámicas
|
|
self.info_labels = {
|
|
"hora": ctk.CTkLabel(self.bottom_bar, text="Hora: --:--:--", font=("Arial", 12), text_color="black"),
|
|
"fecha": ctk.CTkLabel(self.bottom_bar, text="Fecha: --/--/----", font=("Arial", 12), text_color="black"),
|
|
"temperatura": ctk.CTkLabel(self.bottom_bar, text="Temperatura local: --°C", font=("Arial", 12), text_color="black"),
|
|
"emails": ctk.CTkLabel(self.bottom_bar, text="Correos sin leer: 0", font=("Arial", 12), text_color="black"),
|
|
}
|
|
|
|
# Empaquetar las etiquetas horizontalmente
|
|
for label in self.info_labels.values():
|
|
label.pack(side=ctk.LEFT, padx=10, pady=5)
|
|
|
|
|
|
|
|
def dummy_action(self):
|
|
print("Acción no implementada")
|
|
|
|
def create_radio_tab(self, tab):
|
|
"""Crea la interfaz para la funcionalidad de emisoras de radio."""
|
|
self.radio_player = self.thread_manager.radio_player
|
|
|
|
# Lista de emisoras
|
|
radio_stations = {
|
|
"Box Radio UK": "http://uk2.internet-radio.com:8024/",
|
|
"Jazz Radio": "http://us2.internet-radio.com:8443/",
|
|
"Deep House Radio": "http://uk7.internet-radio.com:8000/",
|
|
}
|
|
|
|
# Dropdown para seleccionar emisora
|
|
self.selected_station = ctk.StringVar(value="Selecciona una emisora")
|
|
station_menu = ctk.CTkOptionMenu(tab, variable=self.selected_station, values=list(radio_stations.keys()))
|
|
station_menu.pack(pady=10)
|
|
|
|
# Botón para reproducir
|
|
play_button = ctk.CTkButton(
|
|
tab,
|
|
text="Reproducir",
|
|
command=lambda: self.start_radio(radio_stations[self.selected_station.get()])
|
|
)
|
|
play_button.pack(pady=5)
|
|
|
|
# Botón para detener
|
|
stop_button = ctk.CTkButton(
|
|
tab,
|
|
text="Detener",
|
|
command=self.stop_radio,
|
|
state=tk.DISABLED # Deshabilitado inicialmente
|
|
)
|
|
stop_button.pack(pady=5)
|
|
|
|
# Guardar referencias para habilitar/deshabilitar botones
|
|
self.radio_controls = {"play_button": play_button, "stop_button": stop_button}
|
|
|
|
def start_radio(self, url):
|
|
"""Inicia la reproducción de radio y actualiza los botones."""
|
|
if url == "Selecciona una emisora":
|
|
tk.messagebox.showwarning("Advertencia", "Por favor, selecciona una emisora válida.")
|
|
return
|
|
self.radio_player.play(url)
|
|
self.radio_controls["play_button"].configure(state=tk.DISABLED)
|
|
self.radio_controls["stop_button"].configure(state=tk.NORMAL)
|
|
|
|
def stop_radio(self):
|
|
"""Detiene la reproducción de radio y actualiza los botones."""
|
|
self.radio_player.stop()
|
|
self.radio_controls["play_button"].configure(state=tk.NORMAL)
|
|
self.radio_controls["stop_button"].configure(state=tk.DISABLED) |