| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- """
- Custom Spinner Widget
- A professionally designed animated spinner with rotating arc design.
- """
- from PyQt5.QtWidgets import QWidget
- from PyQt5.QtCore import Qt, QTimer, QRect, QSize
- from PyQt5.QtGui import QPainter, QPen, QColor, QBrush
- class Spinner(QWidget):
- """
- A custom rotating spinner widget with smooth arc animation.
-
- Features:
- - Smooth rotating arc design
- - Customizable colors and sizes
- - Professional appearance
- """
-
- def __init__(self, parent=None, size: int = 60, color: str = "#3498db"):
- """
- Initialize the spinner.
-
- Args:
- parent: Parent widget
- size: Size of the spinner in pixels
- color: Color of the spinner (hex or color name)
- """
- super().__init__(parent)
- self.size = size
- self.color = QColor(color)
- self.angle = 0
- self.setMinimumSize(size + 20, size + 20)
- self.setMaximumSize(size + 20, size + 20)
-
- # Animation timer
- self.timer = QTimer()
- self.timer.timeout.connect(self._rotate)
- self.timer.start(30) # ~33 FPS for smooth animation
-
- def _rotate(self):
- """Update rotation angle."""
- self.angle = (self.angle + 6) % 360 # Rotate 6 degrees each frame
- self.update()
-
- def paintEvent(self, event):
- """Paint the spinner."""
- painter = QPainter(self)
- painter.setRenderHint(QPainter.Antialiasing)
-
- # Center the spinner
- center_x = self.width() // 2
- center_y = self.height() // 2
-
- # Draw rotating arc
- pen = QPen(self.color)
- pen.setWidth(4)
- pen.setCapStyle(Qt.RoundCap)
- painter.setPen(pen)
-
- # Draw the spinning arc
- rect = QRect(center_x - self.size // 2, center_y - self.size // 2, self.size, self.size)
- start_angle = self.angle * 16 # Qt uses 1/16 degree units
- span_angle = 120 * 16 # 120 degree arc
-
- painter.drawArc(rect, start_angle, span_angle)
-
- # Draw subtle background circle
- bg_pen = QPen(QColor("#ecf0f1"))
- bg_pen.setWidth(3)
- painter.setPen(bg_pen)
- painter.drawEllipse(rect)
-
- def stop(self):
- """Stop the spinner animation."""
- self.timer.stop()
-
- def start(self):
- """Start the spinner animation."""
- self.timer.start(30)
-
- def set_color(self, color: str):
- """
- Change the spinner color.
-
- Args:
- color: Color in hex or color name
- """
- self.color = QColor(color)
- self.update()
- class DotsSpinner(QWidget):
- """
- An alternative spinner with rotating dots around a circle.
- """
-
- def __init__(self, parent=None, size: int = 60, color: str = "#3498db", dot_count: int = 8):
- """
- Initialize the dots spinner.
-
- Args:
- parent: Parent widget
- size: Size of the spinner in pixels
- color: Color of the spinner dots
- dot_count: Number of rotating dots
- """
- super().__init__(parent)
- self.size = size
- self.color = QColor(color)
- self.angle = 0
- self.dot_count = dot_count
- self.setMinimumSize(size + 20, size + 20)
- self.setMaximumSize(size + 20, size + 20)
-
- # Animation timer
- self.timer = QTimer()
- self.timer.timeout.connect(self._rotate)
- self.timer.start(30)
-
- def _rotate(self):
- """Update rotation angle."""
- self.angle = (self.angle + 360 / self.dot_count / 8) % 360
- self.update()
-
- def paintEvent(self, event):
- """Paint the spinner with rotating dots."""
- painter = QPainter(self)
- painter.setRenderHint(QPainter.Antialiasing)
-
- # Center the spinner
- center_x = self.width() // 2
- center_y = self.height() // 2
-
- # Draw rotating dots
- import math
- radius = self.size // 2
- dot_radius = 3
-
- for i in range(self.dot_count):
- # Calculate angle for this dot
- dot_angle = (self.angle + (360 / self.dot_count) * i) * math.pi / 180
-
- # Calculate position
- x = center_x + radius * math.cos(dot_angle)
- y = center_y + radius * math.sin(dot_angle)
-
- # Fade effect - dots fade out as they come to the back
- opacity = (i / self.dot_count + 0.5) % 1.0
- color = QColor(self.color)
- color.setAlpha(int(255 * opacity))
-
- # Draw dot
- painter.setPen(Qt.NoPen)
- painter.setBrush(color)
- painter.drawEllipse(int(x - dot_radius), int(y - dot_radius),
- dot_radius * 2, dot_radius * 2)
-
- def stop(self):
- """Stop the spinner animation."""
- self.timer.stop()
-
- def start(self):
- """Start the spinner animation."""
- self.timer.start(30)
-
- def set_color(self, color: str):
- """
- Change the spinner color.
-
- Args:
- color: Color in hex or color name
- """
- self.color = QColor(color)
- self.update()
|