PyQt中自定义Toggle开关按钮动画效果无法生效如何解决?
PyQt5 Toggle开关动画不生效问题修复方案
问题原因
- 普通Python
@property装饰器声明的属性无法被Qt的元对象系统识别,QPropertyAnimation只能操作通过Qt专属的@pyqtProperty装饰器声明的属性。 - 动画初始化时参数调用错误,你误写了
self.animation.setDirection(500),这个方法是用来设置动画播放方向的,正确的设置动画时长的方法是setDuration(500),参数单位为毫秒。
修复后的完整代码
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class ToggleButton(QCheckBox): def __init__(self, width = 70, bgColor = '#777', circleColor = '#DDD', activeColor = '#00BCff', animationCurve = QEasingCurve.OutBounce ): QCheckBox.__init__(self) self.setFixedSize(width, 40) self.setCursor(Qt.PointingHandCursor) self._bg_color = bgColor self._circle_color = circleColor self._active_color = activeColor self._circle_position = 3 self.animation = QPropertyAnimation(self, b"circle_position") self.animation.setEasingCurve(animationCurve) # 修复:设置动画时长为500毫秒 self.animation.setDuration(500) self.stateChanged.connect(self.start_transition) # 修复:改用pyqtProperty声明属性 @pyqtProperty(int) def circle_position(self): return self._circle_position @circle_position.setter def circle_position(self, pos): self._circle_position = pos self.update() def start_transition(self, value): print(self.isChecked()) self.animation.stop() if value: self.animation.setEndValue(self.width() - 26) else: self.animation.setEndValue(3) self.animation.start() def hitButton(self, pos: QPoint): return self.contentsRect().contains(pos) def paintEvent(self, e): p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setPen(Qt.NoPen) rect = QRect(0, 0, self.width(), self.height()) if not self.isChecked(): p.setBrush(QColor(self._bg_color)) p.drawRoundedRect(0, 0, rect.width(), self.height(), self.height() / 2, self.height() / 2) p.setBrush(QColor(self._circle_color)) p.drawEllipse(self._circle_position, 3, 32, 32) else: p.setBrush(QColor(self._active_color)) p.drawRoundedRect(0, 0, rect.width(), self.height(), self.height() / 2, self.height() / 2) p.setBrush(QColor(self._circle_color)) p.drawEllipse(self._circle_position, 3, 32, 32) p.end() class window(QMainWindow): def __init__(self, parent = None): super(window, self).__init__(parent) self.resize(500,500) self.setWindowTitle("PyQt5") self.toggleBtn = ToggleButton() self.container = QFrame() self.layout = QVBoxLayout() self.layout.addWidget(self.toggleBtn, Qt.AlignCenter, Qt.AlignCenter) self.container.setLayout(self.layout) self.setCentralWidget(self.container) def main(): app = QApplication(sys.argv) ex = window() ex.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

