| 19 | |
| 20 | |
| 21 | class RotateButton(QPushButton): |
| 22 | |
| 23 | STARTVALUE = 0 # 起始旋转角度 |
| 24 | ENDVALUE = 360 # 结束旋转角度 |
| 25 | DURATION = 540 # 动画完成总时间 |
| 26 | |
| 27 | def __init__(self, *args, image='', **kwargs): |
| 28 | super(RotateButton, self).__init__(*args, **kwargs) |
| 29 | self.setCursor(Qt.PointingHandCursor) |
| 30 | self._angle = 0 # 角度 |
| 31 | self._padding = 10 # 阴影边距 |
| 32 | self._image = '' # 图片路径 |
| 33 | self._shadowColor = QColor(33, 33, 33) # 阴影颜色 |
| 34 | self._pixmap = None # 图片对象 |
| 35 | # 属性动画 |
| 36 | self._animation = QPropertyAnimation(self, b'angle', self) |
| 37 | self._animation.setLoopCount(1) # 只循环一次 |
| 38 | self.setPixmap(image) |
| 39 | # 绑定提示框 |
| 40 | ToolTip.bind(self) |
| 41 | |
| 42 | def paintEvent(self, event): |
| 43 | """绘制事件""" |
| 44 | text = self.text() |
| 45 | option = QStyleOptionButton() |
| 46 | self.initStyleOption(option) |
| 47 | option.text = '' # 不绘制文字 |
| 48 | painter = QStylePainter(self) |
| 49 | painter.setRenderHint(QStylePainter.Antialiasing) |
| 50 | painter.setRenderHint(QStylePainter.HighQualityAntialiasing) |
| 51 | painter.setRenderHint(QStylePainter.SmoothPixmapTransform) |
| 52 | painter.drawControl(QStyle.CE_PushButton, option) |
| 53 | # 变换坐标为正中间 |
| 54 | painter.translate(self.rect().center()) |
| 55 | painter.rotate(self._angle) # 旋转 |
| 56 | |
| 57 | # 绘制图片 |
| 58 | if self._pixmap and not self._pixmap.isNull(): |
| 59 | w = self.width() |
| 60 | h = self.height() |
| 61 | pos = QPointF(-self._pixmap.width() / 2, -self._pixmap.height() / 2) |
| 62 | painter.drawPixmap(pos, self._pixmap) |
| 63 | elif text: |
| 64 | # 在变换坐标后的正中间画文字 |
| 65 | fm = self.fontMetrics() |
| 66 | w = fm.width(text) |
| 67 | h = fm.height() |
| 68 | rect = QRectF(0 - w * 2, 0 - h, w * 2 * 2, h * 2) |
| 69 | painter.drawText(rect, Qt.AlignCenter, text) |
| 70 | else: |
| 71 | super(RotateButton, self).paintEvent(event) |
| 72 | |
| 73 | def enterEvent(self, _): |
| 74 | """鼠标进入事件""" |
| 75 | # 设置阴影 |
| 76 | # 边框阴影效果 |
| 77 | effect = QGraphicsDropShadowEffect(self) |
| 78 | effect.setBlurRadius(self._padding * 2) |