70 lines
2.5 KiB
Python
70 lines
2.5 KiB
Python
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() |