# C:\PYTHON\MyICR_Suite\app\widgets\loading_overlay.py import logging from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QApplication from PyQt6.QtGui import QColor, QPainter, QFont from PyQt6.QtCore import Qt, QEvent logger = logging.getLogger(__name__) class LoadingOverlay(QWidget): """ Un widget overlay robusto che usa un event filter per coprire il suo genitore. Questo previene errori di rendering (QPainter) e garantisce che la UI rimanga reattiva. """ def __init__(self, parent=None, text: str = "Caricamento in corso..."): super().__init__(parent) # L'overlay deve essere un widget di primo livello per non interferire con il layout del genitore self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.ToolTip) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose) layout = QVBoxLayout(self) layout.setAlignment(Qt.AlignmentFlag.AlignCenter) self.loading_label = QLabel(text, self) font = QFont("Segoe UI", 18) self.loading_label.setFont(font) self.loading_label.setStyleSheet("color: #333333; background-color: transparent;") layout.addWidget(self.loading_label) # Nascondi all'inizio self.hide() # --- MODIFICA CHIAVE: Installa il filtro eventi sul genitore --- if parent: parent.installEventFilter(self) def eventFilter(self, source, event): """Filtra gli eventi del widget genitore.""" if source == self.parent(): if event.type() == QEvent.Type.Resize: self.update_geometry() elif event.type() == QEvent.Type.Move: self.update_geometry() return super().eventFilter(source, event) def update_geometry(self): """Aggiorna la posizione e la dimensione dell'overlay per coprire il genitore.""" if self.parent(): parent_rect = self.parent().rect() # Mappa le coordinate del rettangolo del genitore alle coordinate globali dello schermo top_left = self.parent().mapToGlobal(parent_rect.topLeft()) self.setGeometry(top_left.x(), top_left.y(), parent_rect.width(), parent_rect.height()) def paintEvent(self, event): """Disegna uno sfondo semi-trasparente.""" painter = QPainter(self) painter.setBrush(QColor(240, 240, 240, 220)) painter.setPen(Qt.PenStyle.NoPen) painter.drawRect(self.rect()) def start_loading(self, text: str = None): """Mostra l'overlay e imposta il cursore di attesa.""" if not self.parent(): return if text: self.loading_label.setText(text) self.update_geometry() self.show() self.raise_() QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor) def stop_loading(self): """Nasconde l'overlay e ripristina il cursore.""" QApplication.restoreOverrideCursor() self.hide()