| 41 | |
| 42 | |
| 43 | class RotateButton(QPushButton): |
| 44 | |
| 45 | STARTVALUE = 0 # 起始旋转角度 |
| 46 | ENDVALUE = 360 # 结束旋转角度 |
| 47 | DURATION = 540 # 动画完成总时间 |
| 48 | |
| 49 | def __init__(self, *args, **kwargs): |
| 50 | super(RotateButton, self).__init__(*args, **kwargs) |
| 51 | self.setCursor(Qt.PointingHandCursor) |
| 52 | self._angle = 0 # 角度 |
| 53 | self._padding = 10 # 阴影边距 |
| 54 | self._image = "" # 图片路径 |
| 55 | self._shadowColor = QColor(33, 33, 33) # 阴影颜色 |
| 56 | self._pixmap = None # 图片对象 |
| 57 | # 属性动画 |
| 58 | self._animation = QPropertyAnimation(self, b"angle", self) |
| 59 | self._animation.setLoopCount(1) # 只循环一次 |
| 60 | |
| 61 | def paintEvent(self, event): |
| 62 | """绘制事件""" |
| 63 | text = self.text() |
| 64 | option = QStyleOptionButton() |
| 65 | self.initStyleOption(option) |
| 66 | option.text = "" # 不绘制文字 |
| 67 | painter = QStylePainter(self) |
| 68 | painter.setRenderHint(QStylePainter.Antialiasing) |
| 69 | painter.setRenderHint(QStylePainter.HighQualityAntialiasing) |
| 70 | painter.setRenderHint(QStylePainter.SmoothPixmapTransform) |
| 71 | painter.drawControl(QStyle.CE_PushButton, option) |
| 72 | # 变换坐标为正中间 |
| 73 | painter.translate(self.rect().center()) |
| 74 | painter.rotate(self._angle) # 旋转 |
| 75 | |
| 76 | # 绘制图片 |
| 77 | if self._pixmap and not self._pixmap.isNull(): |
| 78 | w = self.width() |
| 79 | h = self.height() |
| 80 | pos = QPointF(-self._pixmap.width() / 2, -self._pixmap.height() / 2) |
| 81 | painter.drawPixmap(pos, self._pixmap) |
| 82 | elif text: |
| 83 | # 在变换坐标后的正中间画文字 |
| 84 | fm = self.fontMetrics() |
| 85 | w = fm.width(text) |
| 86 | h = fm.height() |
| 87 | rect = QRectF(0 - w * 2, 0 - h, w * 2 * 2, h * 2) |
| 88 | painter.drawText(rect, Qt.AlignCenter, text) |
| 89 | else: |
| 90 | super(RotateButton, self).paintEvent(event) |
| 91 | |
| 92 | def enterEvent(self, _): |
| 93 | """鼠标进入事件""" |
| 94 | # 设置阴影 |
| 95 | # 边框阴影效果 |
| 96 | effect = QGraphicsDropShadowEffect(self) |
| 97 | effect.setBlurRadius(self._padding * 2) |
| 98 | effect.setOffset(0, 0) |
| 99 | effect.setColor(self._shadowColor) |
| 100 | self.setGraphicsEffect(effect) |