loading_screen.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. """
  2. Loading Screen Widget
  3. Displays an animated loading screen with animated GIF and progress indication.
  4. """
  5. from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
  6. from PyQt5.QtCore import Qt, QSize
  7. from PyQt5.QtGui import QFont, QMovie, QPixmap
  8. from pathlib import Path
  9. class LoadingScreen(QWidget):
  10. """
  11. A professional loading screen widget with animated GIF and message.
  12. Features:
  13. - Animated loading GIF
  14. - Centered layout
  15. - Custom messages
  16. - Clean visual design
  17. """
  18. def __init__(self, message: str = "Processing analysis...", parent=None):
  19. """
  20. Initialize the loading screen.
  21. Args:
  22. message: Initial loading message to display
  23. parent: Parent widget
  24. """
  25. super().__init__(parent)
  26. self.message = message
  27. self.movie = None
  28. self.init_ui()
  29. def init_ui(self):
  30. """Initialize UI components."""
  31. layout = QVBoxLayout(self)
  32. layout.setContentsMargins(0, 0, 0, 0)
  33. layout.setSpacing(20)
  34. # Add stretch at top for centering
  35. layout.addStretch()
  36. # Animated GIF label
  37. self.gif_label = QLabel()
  38. self.gif_label.setAlignment(Qt.AlignCenter)
  39. # Load the animated GIF
  40. gif_path = Path(__file__).parent.parent.parent / "assets" / "loading-gif.gif"
  41. if gif_path.exists():
  42. self.movie = QMovie(str(gif_path))
  43. # Set a reasonable size for the GIF
  44. scaled_size = self.movie.scaledSize()
  45. if scaled_size.width() <= 0 or scaled_size.height() <= 0:
  46. self.movie.setScaledSize(QSize(120, 120))
  47. self.gif_label.setMovie(self.movie)
  48. self.movie.start()
  49. else:
  50. # Fallback if GIF not found
  51. self.gif_label.setText("⏳")
  52. self.gif_label.setFont(QFont("Arial", 48))
  53. layout.addWidget(self.gif_label, alignment=Qt.AlignCenter)
  54. # Loading message
  55. self.message_label = QLabel(self.message)
  56. self.message_label.setFont(QFont("Arial", 16, QFont.Bold))
  57. self.message_label.setAlignment(Qt.AlignCenter)
  58. self.message_label.setStyleSheet("color: #2c3e50;")
  59. layout.addWidget(self.message_label, alignment=Qt.AlignCenter)
  60. # Add stretch at bottom for centering
  61. layout.addStretch()
  62. # Set background
  63. self.setStyleSheet("background-color: #ffffff;")
  64. def start_animation(self):
  65. """Start the animation."""
  66. if self.movie:
  67. self.movie.start()
  68. def stop_animation(self):
  69. """Stop the animation."""
  70. if self.movie:
  71. self.movie.stop()
  72. def set_message(self, message: str):
  73. """
  74. Update the loading message.
  75. Args:
  76. message: New loading message
  77. """
  78. self.message_label.setText(message)
  79. def set_status(self, status: str):
  80. """
  81. Update the status text (not used in this simplified version).
  82. Args:
  83. status: Status message (ignored)
  84. """
  85. pass
  86. def cleanup(self):
  87. """Cleanup animation resources."""
  88. self.stop_animation()
  89. if self.movie:
  90. self.movie.deleteLater()
  91. class LoadingOverlay(QWidget):
  92. """
  93. A full-screen loading overlay that can be placed on top of other widgets.
  94. Uses the same simplified loading design as LoadingScreen.
  95. """
  96. def __init__(self, message: str = "Processing...", parent=None):
  97. """
  98. Initialize the loading overlay.
  99. Args:
  100. message: Loading message
  101. parent: Parent widget
  102. """
  103. super().__init__(parent)
  104. self.setWindowFlags(Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint)
  105. self.setAttribute(Qt.WA_TranslucentBackground)
  106. layout = QVBoxLayout(self)
  107. layout.setContentsMargins(0, 0, 0, 0)
  108. # Semi-transparent background
  109. self.setStyleSheet("background-color: rgba(0, 0, 0, 0.3);")
  110. # Create centered loading widget
  111. self.loading_widget = QWidget()
  112. self.loading_layout = QVBoxLayout(self.loading_widget)
  113. self.loading_layout.setContentsMargins(40, 40, 40, 40)
  114. self.loading_layout.setSpacing(20)
  115. # Background container
  116. self.loading_widget.setStyleSheet("""
  117. QWidget {
  118. background-color: #ffffff;
  119. border-radius: 12px;
  120. border: 1px solid #ecf0f1;
  121. }
  122. """)
  123. # Animated GIF
  124. self.gif_label = QLabel()
  125. self.gif_label.setAlignment(Qt.AlignCenter)
  126. gif_path = Path(__file__).parent.parent.parent / "assets" / "loading-gif.gif"
  127. self.movie = None
  128. if gif_path.exists():
  129. self.movie = QMovie(str(gif_path))
  130. self.gif_label.setMovie(self.movie)
  131. self.movie.start()
  132. else:
  133. self.gif_label.setText("⏳")
  134. self.gif_label.setFont(QFont("Arial", 48))
  135. self.loading_layout.addWidget(self.gif_label, alignment=Qt.AlignCenter)
  136. # Message
  137. message_label = QLabel(message)
  138. message_label.setFont(QFont("Arial", 14, QFont.Bold))
  139. message_label.setAlignment(Qt.AlignCenter)
  140. message_label.setStyleSheet("color: #2c3e50;")
  141. self.loading_layout.addWidget(message_label)
  142. layout.addStretch()
  143. layout.addWidget(self.loading_widget, alignment=Qt.AlignCenter)
  144. layout.addStretch()
  145. def cleanup(self):
  146. """Stop animation and cleanup."""
  147. if self.movie:
  148. self.movie.stop()
  149. self.movie.deleteLater()