components.circular_progress_bar
1from PyQt6.QtCore import Qt, QRectF 2from PyQt6.QtGui import QColor, QPainter, QPen, QFont 3from PyQt6.QtWidgets import QWidget 4 5 6class CircularProgress(QWidget): 7 """ 8 A customizable **circular progress bar widget** for PyQt6 applications. 9 10 This widget visually represents a percentage-based progress value (0–100) 11 as a circular arc with a numeric label at its center. It is lightweight, 12 anti-aliased, and supports dynamic color changes. 13 14 --- 15 **Features** 16 - Smooth circular progress rendering with anti-aliasing 17 - Adjustable color via `setColor()` 18 - Automatically scales with parent widget size 19 - Displays numeric percentage text in the center 20 --- 21 22 **Parameters** 23 - `color (str | QColor)`: Initial color for the progress arc. 24 Accepts either a hex string (e.g., "#3498DB") or a `QColor` instance. 25 26 **Example** 27 ```python 28 progress = CircularProgress("#00B894") 29 progress.setValue(75) 30 ``` 31 """ 32 33 def __init__(self, color: str = "#3498DB"): 34 """ 35 Initialize the circular progress widget. 36 37 Args: 38 color (str): Hex color string for the progress arc (default: "#3498DB"). 39 """ 40 super().__init__() 41 self.value = 0 # Current progress value (0–100) 42 self.color = QColor(color) # Active progress color 43 44 self.setMaximumSize(300, 300) 45 46 def setValue(self, val: int): 47 """ 48 Update the progress value and refresh the widget. 49 50 Args: 51 val (int): New progress value (0–100). Values outside this range are clamped. 52 53 Notes: 54 This method triggers a repaint using `update()`. 55 """ 56 self.value = max(0, min(100, int(val))) 57 self.update() 58 59 def setColor(self, color: str | QColor): 60 """ 61 Change the color of the progress arc. 62 63 Args: 64 color (str | QColor): The new color for the progress indicator. 65 Can be a hex string or a `QColor` instance. 66 67 Example: 68 ```python 69 progress.setColor("#E74C3C") # Set to red 70 ``` 71 """ 72 if isinstance(color, str): 73 self.color = QColor(color) 74 else: 75 self.color = color 76 self.update() 77 78 def sizeHint(self): 79 """ 80 Suggest an appropriate default size for the widget. 81 82 Returns: 83 QSize: The preferred size of the widget, matching its parent if available. 84 """ 85 return self.parentWidget().size() if self.parentWidget() else super().sizeHint() 86 87 def paintEvent(self, event): 88 """ 89 Handle the paint event to draw the circular progress indicator. 90 91 The widget draws: 92 1. A **light gray background circle** 93 2. A **colored progress arc** proportional to the current value 94 3. A **percentage label** centered within the circle 95 96 Args: 97 event (QPaintEvent): The paint event object automatically provided by Qt. 98 """ 99 width = self.width() 100 height = self.height() 101 size = min(width, height) # Ensure square aspect ratio 102 103 # Center the circle in the available space 104 x_offset = int((width - size) / 2) 105 y_offset = int((height - size) / 2) 106 107 painter = QPainter(self) 108 painter.setRenderHint(QPainter.RenderHint.Antialiasing) 109 110 # --- Draw background circle --- 111 painter.setPen(Qt.PenStyle.NoPen) 112 painter.setBrush(QColor("#f0f0f0")) # Light gray background 113 painter.drawEllipse(x_offset, y_offset, int(size), int(size)) 114 115 # --- Draw progress arc --- 116 pen_width = max(5, int(size / 12)) # Adaptive thickness 117 pen = QPen(self.color) 118 pen.setWidth(pen_width) 119 pen.setCapStyle(Qt.PenCapStyle.RoundCap) 120 painter.setPen(pen) 121 painter.setBrush(Qt.BrushStyle.NoBrush) 122 123 # Define drawing area for the arc 124 rect = QRectF( 125 x_offset + pen_width / 2, 126 y_offset + pen_width / 2, 127 size - pen_width, 128 size - pen_width 129 ) 130 angle_span = int(360 * self.value / 100) 131 painter.drawArc(rect, -90 * 16, -angle_span * 16) # Start from top center 132 133 # --- Draw percentage text --- 134 font_size = max(5, int(size / 9)) 135 painter.setPen(QColor("#2C3E50")) # Dark blue-gray text 136 painter.setFont(QFont("Arial", font_size, QFont.Weight.Bold)) 137 painter.drawText(rect, Qt.AlignmentFlag.AlignCenter, f"{self.value}%")
7class CircularProgress(QWidget): 8 """ 9 A customizable **circular progress bar widget** for PyQt6 applications. 10 11 This widget visually represents a percentage-based progress value (0–100) 12 as a circular arc with a numeric label at its center. It is lightweight, 13 anti-aliased, and supports dynamic color changes. 14 15 --- 16 **Features** 17 - Smooth circular progress rendering with anti-aliasing 18 - Adjustable color via `setColor()` 19 - Automatically scales with parent widget size 20 - Displays numeric percentage text in the center 21 --- 22 23 **Parameters** 24 - `color (str | QColor)`: Initial color for the progress arc. 25 Accepts either a hex string (e.g., "#3498DB") or a `QColor` instance. 26 27 **Example** 28 ```python 29 progress = CircularProgress("#00B894") 30 progress.setValue(75) 31 ``` 32 """ 33 34 def __init__(self, color: str = "#3498DB"): 35 """ 36 Initialize the circular progress widget. 37 38 Args: 39 color (str): Hex color string for the progress arc (default: "#3498DB"). 40 """ 41 super().__init__() 42 self.value = 0 # Current progress value (0–100) 43 self.color = QColor(color) # Active progress color 44 45 self.setMaximumSize(300, 300) 46 47 def setValue(self, val: int): 48 """ 49 Update the progress value and refresh the widget. 50 51 Args: 52 val (int): New progress value (0–100). Values outside this range are clamped. 53 54 Notes: 55 This method triggers a repaint using `update()`. 56 """ 57 self.value = max(0, min(100, int(val))) 58 self.update() 59 60 def setColor(self, color: str | QColor): 61 """ 62 Change the color of the progress arc. 63 64 Args: 65 color (str | QColor): The new color for the progress indicator. 66 Can be a hex string or a `QColor` instance. 67 68 Example: 69 ```python 70 progress.setColor("#E74C3C") # Set to red 71 ``` 72 """ 73 if isinstance(color, str): 74 self.color = QColor(color) 75 else: 76 self.color = color 77 self.update() 78 79 def sizeHint(self): 80 """ 81 Suggest an appropriate default size for the widget. 82 83 Returns: 84 QSize: The preferred size of the widget, matching its parent if available. 85 """ 86 return self.parentWidget().size() if self.parentWidget() else super().sizeHint() 87 88 def paintEvent(self, event): 89 """ 90 Handle the paint event to draw the circular progress indicator. 91 92 The widget draws: 93 1. A **light gray background circle** 94 2. A **colored progress arc** proportional to the current value 95 3. A **percentage label** centered within the circle 96 97 Args: 98 event (QPaintEvent): The paint event object automatically provided by Qt. 99 """ 100 width = self.width() 101 height = self.height() 102 size = min(width, height) # Ensure square aspect ratio 103 104 # Center the circle in the available space 105 x_offset = int((width - size) / 2) 106 y_offset = int((height - size) / 2) 107 108 painter = QPainter(self) 109 painter.setRenderHint(QPainter.RenderHint.Antialiasing) 110 111 # --- Draw background circle --- 112 painter.setPen(Qt.PenStyle.NoPen) 113 painter.setBrush(QColor("#f0f0f0")) # Light gray background 114 painter.drawEllipse(x_offset, y_offset, int(size), int(size)) 115 116 # --- Draw progress arc --- 117 pen_width = max(5, int(size / 12)) # Adaptive thickness 118 pen = QPen(self.color) 119 pen.setWidth(pen_width) 120 pen.setCapStyle(Qt.PenCapStyle.RoundCap) 121 painter.setPen(pen) 122 painter.setBrush(Qt.BrushStyle.NoBrush) 123 124 # Define drawing area for the arc 125 rect = QRectF( 126 x_offset + pen_width / 2, 127 y_offset + pen_width / 2, 128 size - pen_width, 129 size - pen_width 130 ) 131 angle_span = int(360 * self.value / 100) 132 painter.drawArc(rect, -90 * 16, -angle_span * 16) # Start from top center 133 134 # --- Draw percentage text --- 135 font_size = max(5, int(size / 9)) 136 painter.setPen(QColor("#2C3E50")) # Dark blue-gray text 137 painter.setFont(QFont("Arial", font_size, QFont.Weight.Bold)) 138 painter.drawText(rect, Qt.AlignmentFlag.AlignCenter, f"{self.value}%")
A customizable circular progress bar widget for PyQt6 applications.
This widget visually represents a percentage-based progress value (0–100) as a circular arc with a numeric label at its center. It is lightweight, anti-aliased, and supports dynamic color changes.
Features
- Smooth circular progress rendering with anti-aliasing
- Adjustable color via
setColor() - Automatically scales with parent widget size
- Displays numeric percentage text in the center
Parameters
color (str | QColor): Initial color for the progress arc. Accepts either a hex string (e.g., "#3498DB") or aQColorinstance.
Example
progress = CircularProgress("#00B894")
progress.setValue(75)
34 def __init__(self, color: str = "#3498DB"): 35 """ 36 Initialize the circular progress widget. 37 38 Args: 39 color (str): Hex color string for the progress arc (default: "#3498DB"). 40 """ 41 super().__init__() 42 self.value = 0 # Current progress value (0–100) 43 self.color = QColor(color) # Active progress color 44 45 self.setMaximumSize(300, 300)
Initialize the circular progress widget.
Args: color (str): Hex color string for the progress arc (default: "#3498DB").
47 def setValue(self, val: int): 48 """ 49 Update the progress value and refresh the widget. 50 51 Args: 52 val (int): New progress value (0–100). Values outside this range are clamped. 53 54 Notes: 55 This method triggers a repaint using `update()`. 56 """ 57 self.value = max(0, min(100, int(val))) 58 self.update()
Update the progress value and refresh the widget.
Args: val (int): New progress value (0–100). Values outside this range are clamped.
Notes:
This method triggers a repaint using update().
60 def setColor(self, color: str | QColor): 61 """ 62 Change the color of the progress arc. 63 64 Args: 65 color (str | QColor): The new color for the progress indicator. 66 Can be a hex string or a `QColor` instance. 67 68 Example: 69 ```python 70 progress.setColor("#E74C3C") # Set to red 71 ``` 72 """ 73 if isinstance(color, str): 74 self.color = QColor(color) 75 else: 76 self.color = color 77 self.update()
Change the color of the progress arc.
Args:
color (str | QColor): The new color for the progress indicator.
Can be a hex string or a QColor instance.
Example:
progress.setColor("#E74C3C") # Set to red
79 def sizeHint(self): 80 """ 81 Suggest an appropriate default size for the widget. 82 83 Returns: 84 QSize: The preferred size of the widget, matching its parent if available. 85 """ 86 return self.parentWidget().size() if self.parentWidget() else super().sizeHint()
Suggest an appropriate default size for the widget.
Returns: QSize: The preferred size of the widget, matching its parent if available.
88 def paintEvent(self, event): 89 """ 90 Handle the paint event to draw the circular progress indicator. 91 92 The widget draws: 93 1. A **light gray background circle** 94 2. A **colored progress arc** proportional to the current value 95 3. A **percentage label** centered within the circle 96 97 Args: 98 event (QPaintEvent): The paint event object automatically provided by Qt. 99 """ 100 width = self.width() 101 height = self.height() 102 size = min(width, height) # Ensure square aspect ratio 103 104 # Center the circle in the available space 105 x_offset = int((width - size) / 2) 106 y_offset = int((height - size) / 2) 107 108 painter = QPainter(self) 109 painter.setRenderHint(QPainter.RenderHint.Antialiasing) 110 111 # --- Draw background circle --- 112 painter.setPen(Qt.PenStyle.NoPen) 113 painter.setBrush(QColor("#f0f0f0")) # Light gray background 114 painter.drawEllipse(x_offset, y_offset, int(size), int(size)) 115 116 # --- Draw progress arc --- 117 pen_width = max(5, int(size / 12)) # Adaptive thickness 118 pen = QPen(self.color) 119 pen.setWidth(pen_width) 120 pen.setCapStyle(Qt.PenCapStyle.RoundCap) 121 painter.setPen(pen) 122 painter.setBrush(Qt.BrushStyle.NoBrush) 123 124 # Define drawing area for the arc 125 rect = QRectF( 126 x_offset + pen_width / 2, 127 y_offset + pen_width / 2, 128 size - pen_width, 129 size - pen_width 130 ) 131 angle_span = int(360 * self.value / 100) 132 painter.drawArc(rect, -90 * 16, -angle_span * 16) # Start from top center 133 134 # --- Draw percentage text --- 135 font_size = max(5, int(size / 9)) 136 painter.setPen(QColor("#2C3E50")) # Dark blue-gray text 137 painter.setFont(QFont("Arial", font_size, QFont.Weight.Bold)) 138 painter.drawText(rect, Qt.AlignmentFlag.AlignCenter, f"{self.value}%")
Handle the paint event to draw the circular progress indicator.
The widget draws:
- A light gray background circle
- A colored progress arc proportional to the current value
- A percentage label centered within the circle
Args: event (QPaintEvent): The paint event object automatically provided by Qt.