""" Loading Screen Widget Displays an animated loading screen with animated GIF and progress indication. """ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel from PyQt5.QtCore import Qt, QSize from PyQt5.QtGui import QFont, QMovie, QPixmap from pathlib import Path class LoadingScreen(QWidget): """ A professional loading screen widget with animated GIF and message. Features: - Animated loading GIF - Centered layout - Custom messages - Clean visual design """ def __init__(self, message: str = "Processing analysis...", parent=None): """ Initialize the loading screen. Args: message: Initial loading message to display parent: Parent widget """ super().__init__(parent) self.message = message self.movie = None self.init_ui() def init_ui(self): """Initialize UI components.""" layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(20) # Add stretch at top for centering layout.addStretch() # Animated GIF label self.gif_label = QLabel() self.gif_label.setAlignment(Qt.AlignCenter) # Load the animated GIF gif_path = Path(__file__).parent.parent.parent / "assets" / "loading-gif.gif" if gif_path.exists(): self.movie = QMovie(str(gif_path)) # Set a reasonable size for the GIF scaled_size = self.movie.scaledSize() if scaled_size.width() <= 0 or scaled_size.height() <= 0: self.movie.setScaledSize(QSize(120, 120)) self.gif_label.setMovie(self.movie) self.movie.start() else: # Fallback if GIF not found self.gif_label.setText("⏳") self.gif_label.setFont(QFont("Arial", 48)) layout.addWidget(self.gif_label, alignment=Qt.AlignCenter) # Loading message self.message_label = QLabel(self.message) self.message_label.setFont(QFont("Arial", 16, QFont.Bold)) self.message_label.setAlignment(Qt.AlignCenter) self.message_label.setStyleSheet("color: #2c3e50;") layout.addWidget(self.message_label, alignment=Qt.AlignCenter) # Add stretch at bottom for centering layout.addStretch() # Set background self.setStyleSheet("background-color: #ffffff;") def start_animation(self): """Start the animation.""" if self.movie: self.movie.start() def stop_animation(self): """Stop the animation.""" if self.movie: self.movie.stop() def set_message(self, message: str): """ Update the loading message. Args: message: New loading message """ self.message_label.setText(message) def set_status(self, status: str): """ Update the status text (not used in this simplified version). Args: status: Status message (ignored) """ pass def cleanup(self): """Cleanup animation resources.""" self.stop_animation() if self.movie: self.movie.deleteLater() class LoadingOverlay(QWidget): """ A full-screen loading overlay that can be placed on top of other widgets. Uses the same simplified loading design as LoadingScreen. """ def __init__(self, message: str = "Processing...", parent=None): """ Initialize the loading overlay. Args: message: Loading message parent: Parent widget """ super().__init__(parent) self.setWindowFlags(Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint) self.setAttribute(Qt.WA_TranslucentBackground) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) # Semi-transparent background self.setStyleSheet("background-color: rgba(0, 0, 0, 0.3);") # Create centered loading widget self.loading_widget = QWidget() self.loading_layout = QVBoxLayout(self.loading_widget) self.loading_layout.setContentsMargins(40, 40, 40, 40) self.loading_layout.setSpacing(20) # Background container self.loading_widget.setStyleSheet(""" QWidget { background-color: #ffffff; border-radius: 12px; border: 1px solid #ecf0f1; } """) # Animated GIF self.gif_label = QLabel() self.gif_label.setAlignment(Qt.AlignCenter) gif_path = Path(__file__).parent.parent.parent / "assets" / "loading-gif.gif" self.movie = None if gif_path.exists(): self.movie = QMovie(str(gif_path)) self.gif_label.setMovie(self.movie) self.movie.start() else: self.gif_label.setText("⏳") self.gif_label.setFont(QFont("Arial", 48)) self.loading_layout.addWidget(self.gif_label, alignment=Qt.AlignCenter) # Message message_label = QLabel(message) message_label.setFont(QFont("Arial", 14, QFont.Bold)) message_label.setAlignment(Qt.AlignCenter) message_label.setStyleSheet("color: #2c3e50;") self.loading_layout.addWidget(message_label) layout.addStretch() layout.addWidget(self.loading_widget, alignment=Qt.AlignCenter) layout.addStretch() def cleanup(self): """Stop animation and cleanup.""" if self.movie: self.movie.stop() self.movie.deleteLater()