| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- from PyQt6.QtWidgets import QCheckBox
- from PyQt6.QtCore import (
- Qt,
- QPropertyAnimation,
- pyqtProperty,
- QRectF,
- QSize
- )
- from PyQt6.QtGui import QPainter, QColor
- class Switch(QCheckBox):
- def __init__(self, parent=None):
- super().__init__(parent)
- self.setCursor(Qt.CursorShape.PointingHandCursor)
- self.setFixedSize(50, 26)
- self._offset = 3
- self._radius = 10
- self._animation = QPropertyAnimation(self, b"offset", self)
- self._animation.setDuration(180)
- self._bg_off = QColor("#bdc3c7")
- self._bg_on = QColor("#2ecc71")
- self._circle_color = QColor("white")
- self.toggled.connect(self.start_transition)
- self.setTristate(False)
- self.setText("")
- # Taille recommandée
- def sizeHint(self):
- return QSize(50, 26)
- # Animation
- def start_transition(self, checked):
- self._animation.stop()
- start = self._offset
- end = self.width() - self._radius*2 - 3 if checked else 3
- self._animation.setStartValue(start)
- self._animation.setEndValue(end)
- self._animation.start()
- # Dessin
- def paintEvent(self, event):
- painter = QPainter(self)
- painter.setRenderHint(QPainter.RenderHint.Antialiasing)
- # Background
- if self.isChecked():
- painter.setBrush(self._bg_on)
- else:
- painter.setBrush(self._bg_off)
- painter.setPen(Qt.PenStyle.NoPen)
- painter.drawRoundedRect(
- 0, 0,
- self.width(),
- self.height(),
- self.height() / 2,
- self.height() / 2
- )
- # Cercle
- painter.setBrush(self._circle_color)
- painter.drawEllipse(
- QRectF(
- self._offset,
- (self.height() - self._radius*2)/2,
- self._radius*2,
- self._radius*2
- )
- )
- # Property animable
- def get_offset(self):
- return self._offset
-
- def mouseReleaseEvent(self, event):
- if event.button() == Qt.MouseButton.LeftButton:
- self.setChecked(not self.isChecked())
- super().mouseReleaseEvent(event)
- def set_offset(self, value):
- self._offset = value
- self.update()
- offset = pyqtProperty(float, get_offset, set_offset)
|