"""Application entry point for the warehouse desktop tool. This module wires together the shared async database client, the global background event loop and the different Tk/CustomTkinter windows exposed by the project. """ import asyncio import sys import tkinter as tk import customtkinter as ctk from async_loop_singleton import get_global_loop from async_msssql_query import AsyncMSSQLClient, make_mssql_dsn from layout_window import open_layout_window from reset_corsie import open_reset_corsie_window from search_pallets import open_search_window from view_celle_multiple import open_celle_multiple_window # Try factory, else frame, else app (senza passare conn_str all'App) try: from gestione_pickinglist import create_frame as create_pickinglist_frame except Exception: try: from gestione_pickinglist import GestionePickingListFrame as _PLFrame def create_pickinglist_frame(parent, db_client=None, conn_str=None): """Build the picking list UI using the frame-based fallback.""" ctk.set_appearance_mode("light") ctk.set_default_color_theme("green") return _PLFrame(parent, db_client=db_client, conn_str=conn_str) except Exception: from gestione_pickinglist import GestionePickingListApp as _PLApp def create_pickinglist_frame(parent, db_client=None, conn_str=None): """Fallback used only by legacy app-style picking list implementations.""" app = _PLApp() app.mainloop() return tk.Frame(parent) # ---- Config ---- SERVER = r"mde3\gesterp" DBNAME = "Mediseawall" USER = "sa" PASSWORD = "1Password1" if sys.platform.startswith("win"): try: asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) except Exception: pass # Create one global loop and make it the default everywhere. _loop = get_global_loop() asyncio.set_event_loop(_loop) def _noop(*args, **kwargs): """Compatibility no-op used when optional Tk DPI hooks are missing.""" return None if not hasattr(tk.Toplevel, "block_update_dimensions_event"): tk.Toplevel.block_update_dimensions_event = _noop # type: ignore[attr-defined] if not hasattr(tk.Toplevel, "unblock_update_dimensions_event"): tk.Toplevel.unblock_update_dimensions_event = _noop # type: ignore[attr-defined] dsn_app = make_mssql_dsn(server=SERVER, database=DBNAME, user=USER, password=PASSWORD) db_app = AsyncMSSQLClient(dsn_app) def open_pickinglist_window(parent: tk.Misc, db_client: AsyncMSSQLClient): """Open the picking list window while minimizing initial flicker.""" win = ctk.CTkToplevel(parent) win.title("Gestione Picking List") win.geometry("1200x700+0+100") win.minsize(1000, 560) # Keep the toplevel hidden while its content is being created. try: win.withdraw() win.attributes("-alpha", 0.0) except Exception: pass frame = create_pickinglist_frame(win, db_client=db_client) try: frame.pack(fill="both", expand=True) except Exception: pass # Show the window only when the layout is ready. try: win.update_idletasks() try: win.transient(parent) except Exception: pass try: win.deiconify() except Exception: pass win.lift() try: win.focus_force() except Exception: pass try: win.attributes("-alpha", 1.0) except Exception: pass except Exception: pass win.bind("", lambda e: win.destroy()) win.protocol("WM_DELETE_WINDOW", win.destroy) return win class Launcher(ctk.CTk): """Main launcher window that exposes the available warehouse tools.""" def __init__(self): """Create the launcher toolbar and wire every button to a feature window.""" super().__init__() self.title("Warehouse 1.0.0") self.geometry("1200x70+0+0") wrap = ctk.CTkFrame(self) wrap.pack(pady=10, fill="x") ctk.CTkButton( wrap, text="Gestione Corsie", command=lambda: open_reset_corsie_window(self, db_app), ).grid(row=0, column=0, padx=6, pady=6, sticky="ew") ctk.CTkButton( wrap, text="Gestione Layout", command=lambda: open_layout_window(self, db_app), ).grid(row=0, column=1, padx=6, pady=6, sticky="ew") ctk.CTkButton( wrap, text="UDC Fantasma", command=lambda: open_celle_multiple_window(self, db_app), ).grid(row=0, column=2, padx=6, pady=6, sticky="ew") ctk.CTkButton( wrap, text="Ricerca UDC", command=lambda: open_search_window(self, db_app), ).grid(row=0, column=3, padx=6, pady=6, sticky="ew") ctk.CTkButton( wrap, text="Gestione Picking List", command=lambda: open_pickinglist_window(self, db_app), ).grid(row=0, column=4, padx=6, pady=6, sticky="ew") for i in range(5): wrap.grid_columnconfigure(i, weight=1) def _on_close(): """Dispose shared resources before closing the launcher.""" try: fut = asyncio.run_coroutine_threadsafe(db_app.dispose(), _loop) try: fut.result(timeout=2) except Exception: pass finally: self.destroy() self.protocol("WM_DELETE_WINDOW", _on_close) if __name__ == "__main__": ctk.set_appearance_mode("light") ctk.set_default_color_theme("green") Launcher().mainloop()