Untitled
unknown
plain_text
10 months ago
5.7 kB
20
Indexable
class LidAlertScreen(ctk.CTkToplevel):
def __init__(self, parent, reed_switch, main_root, on_close=None):
super().__init__(parent)
self.on_close = on_close
self.reed_switch = reed_switch
self.main_root = main_root
self._destroyed = False
self._destroy_lock = threading.Lock()
self._monitor_thread = None
# Retrieve current settings from main root
self.language = getattr(self.main_root, 'LANGUAGE', 'EN')
self.dark_mode = getattr(self.main_root, 'DARK_MODE', False)
# Set up the UI
self._setup_ui()
# Start monitoring in a controlled way
self._start_monitoring()
def _setup_ui(self):
"""Set up all UI elements"""
# Configure colors based on dark mode
bg_color = '#1c1c1e' if self.dark_mode else '#f5f5f7'
border_color = '#2c2c2e' if self.dark_mode else '#e5e5e7'
text_color = 'white' if self.dark_mode else 'black'
# Configure window
self.configure(fg_color=bg_color)
self.overrideredirect(True)
self.geometry(f"{self.winfo_screenwidth()}x{self.winfo_screenheight()}+0+0")
self.protocol("WM_DELETE_WINDOW", lambda: None)
self.attributes('-topmost', True)
# Create main container with padding
self.container = ctk.CTkFrame(self, fg_color=bg_color, corner_radius=0)
self.container.pack(fill='both', expand=True, padx=30, pady=30)
# Add border frame
self.border_frame = ctk.CTkFrame(
self.container,
fg_color=border_color,
corner_radius=10
)
self.border_frame.pack(fill='both', expand=True, padx=10, pady=10)
# Create alert box with pastel red background
pastel_red = "#FFB3B3"
self.alert_box = ctk.CTkFrame(
self.border_frame,
fg_color=pastel_red,
corner_radius=8
)
self.alert_box.pack(fill='both', expand=True, padx=5, pady=5)
# Add warning message
message_text = TRANSLATIONS[self.language].get(
'lid_open_warning',
"WARNING: Lid is open!\nPlease close the lid to continue."
)
self.message_label = ctk.CTkLabel(
self.alert_box,
text=message_text,
font=('Dongle', 36),
text_color='#000000'
)
self.message_label.place(relx=0.5, rely=0.35, anchor='center')
# Add warning icon
try:
icon_image = ctk.CTkImage(
light_image=Image.open("icons/circle-alert-b.png"),
dark_image=Image.open("icons/circle-alert-b.png"),
size=(55, 55)
)
self.icon_label = ctk.CTkLabel(
self.alert_box,
image=icon_image,
text=""
)
except Exception as e:
print(f"Error loading warning icon: {e}")
self.icon_label = ctk.CTkLabel(
self.alert_box,
text="⚠",
font=('Dongle', 48)
)
self.icon_label.place(relx=0.5, rely=0.55, anchor='center')
def _start_monitoring(self):
"""Start monitoring thread with proper control"""
if not self._destroyed:
self._monitor_thread = threading.Thread(target=self.monitor_lid, daemon=True)
self._monitor_thread.start()
def handle_lid_closed(self):
"""Synchronized lid closed handler"""
with self._destroy_lock:
if not self._destroyed:
self._destroyed = True
# Schedule destruction on main thread with a small delay
self.after(100, self._safe_destroy)
if self.on_close:
self.after(0, self.on_close)
def _safe_destroy(self):
"""Safe destruction with proper thread handling"""
try:
with self._destroy_lock:
if not self._destroyed:
return
if self._monitor_thread and self._monitor_thread.is_alive():
self._monitor_thread.join(timeout=0.1)
self.destroy()
except tkinter.TclError:
pass
except Exception as e:
print(f"Safe destroy error: {e}")
def monitor_lid(self):
"""Thread-safe lid monitoring"""
while True:
try:
with self._destroy_lock:
if self._destroyed:
break
try:
if self.reed_switch.is_pressed:
self.after(0, self.handle_lid_closed)
break
except Exception:
# Reed switch might be closed, exit gracefully
break
time.sleep(0.1)
except RuntimeError:
# Handle interpreter shutdown
break
except Exception as e:
print(f"Monitor error: {e}")
break
def cleanup(self):
"""Enhanced cleanup with thread synchronization"""
with self._destroy_lock:
if self._destroyed:
return
self._destroyed = True
try:
self.after(100, self._safe_destroy)
except Exception as e:
print(f"Cleanup error: {e}")Editor is loading...
Leave a Comment