from PySide6.QtWidgets import QCheckBox from PySide6.QtCore import Property, QSize, Qt, QRect from PySide6.QtGui import QPainter, QColor, QBrush, QPen class ToggleButton(QCheckBox): """아이폰 스타일의 커스텀 토글 스위치""" def __init__(self, width=50, bg_color="#777", circle_color="#DDD", active_color="#00BCff", disabled_color="#444"): super().__init__() self.setFixedSize(width, 28) self.setCursor(Qt.PointingHandCursor) self._bg_color = bg_color self._circle_color = circle_color self._active_color = active_color self._disabled_color = disabled_color self._circle_position = 3 self.stateChanged.connect(self.start_animation) def start_animation(self, state): self.update() # 애니메이션 없이 즉시 변경 (필요시 QPropertyAnimation 추가 가능) def mousePressEvent(self, event): """마우스 클릭 이벤트 명시적 처리""" if event.button() == Qt.LeftButton and self.isEnabled(): self.setChecked(not self.isChecked()) event.accept() else: super().mousePressEvent(event) def paintEvent(self, e): p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) rect = self.rect() # 비활성화 상태 if not self.isEnabled(): p.setBrush(QColor(self._disabled_color)) p.setPen(Qt.NoPen) p.drawRoundedRect(0, 0, rect.width(), rect.height(), rect.height() / 2, rect.height() / 2) # 어두운 원 circle_dia = rect.height() - 6 p.setBrush(QColor("#555")) p.drawEllipse(3, 3, circle_dia, circle_dia) p.end() return # 배경 그리기 (Capsule 모양) if self.isChecked(): p.setBrush(QColor(self._active_color)) p.setPen(Qt.NoPen) else: p.setBrush(QColor(self._bg_color)) p.setPen(Qt.NoPen) p.drawRoundedRect(0, 0, rect.width(), rect.height(), rect.height() / 2, rect.height() / 2) # 원 그리기 circle_dia = rect.height() - 6 p.setBrush(QColor(self._circle_color)) if self.isChecked(): p.drawEllipse(rect.width() - circle_dia - 3, 3, circle_dia, circle_dia) else: p.drawEllipse(3, 3, circle_dia, circle_dia) p.end()