from PySide6.QtWidgets import QApplication, QPushButton, QMainWindow, QMessageBox from PySide6.QtCore import QPropertyAnimation, QPoint, QParallelAnimationGroup, QEasingCurve, Property from PySide6.QtGui import QColor, QPainter, QBrush from PySide6.QtCore import Qt import sys import Constant class RippleButton(QPushButton): def __init__(self, text, parent=None): super().__init__(text, parent) self._ripple_radius = 0 self._ripple_opacity = 1.0 self.ripple_position = QPoint() self.animation_group = QParallelAnimationGroup(self) # 设置父对象 self.setStyleSheet("background-color: #3498db; color: white; border-radius: 5px; padding: 10px;") self.setAttribute(Qt.WA_StaticContents) def paintEvent(self, event): super().paintEvent(event) if self._ripple_radius > 0: painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) color = QColor(255, 255, 255) color.setAlphaF(self._ripple_opacity) painter.setBrush(QBrush(color)) painter.setPen(Qt.NoPen) painter.drawEllipse(self.ripple_position, self._ripple_radius, self._ripple_radius) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.ripple_position = event.pos() self.startRippleEffect() super().mousePressEvent(event) def startRippleEffect(self): # 取消之前的动画 self.animation_group.stop() self.animation_group.clear() # 创建半径动画 radius_animation = QPropertyAnimation(self, b"rippleRadius") radius_animation.setDuration(600) radius_animation.setStartValue(0) # 计算最大半径,确保覆盖按钮 max_radius = max(self.width(), self.height()) * 1.5 radius_animation.setEndValue(max_radius) radius_animation.setEasingCurve(QEasingCurve.OutQuad) # 创建透明度动画 opacity_animation = QPropertyAnimation(self, b"rippleOpacity") opacity_animation.setDuration(600) opacity_animation.setStartValue(0.5) # 初始透明度可以调整 opacity_animation.setEndValue(0.0) opacity_animation.setEasingCurve(QEasingCurve.OutQuad) # 将动画添加到动画组 self.animation_group.addAnimation(radius_animation) self.animation_group.addAnimation(opacity_animation) self.animation_group.start() # 使用 @Property 装饰器正确定义属性 def getRippleRadius(self): return self._ripple_radius def setRippleRadius(self, radius): self._ripple_radius = radius self.update() rippleRadius = Property(float, getRippleRadius, setRippleRadius) def getRippleOpacity(self): return self._ripple_opacity def setRippleOpacity(self, opacity): self._ripple_opacity = opacity self.update() rippleOpacity = Property(float, getRippleOpacity, setRippleOpacity) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("水滴扩散按钮示例") self.setFixedSize(400, 300) self.button = RippleButton("点击我", self) self.button.setGeometry(150, 130, 100, 40) self.button.clicked.connect(self.on_button_click) def on_button_click(self): print("按钮被点击了!") QMessageBox.information(None, "提示", Constant.str_feed_photo_error_msgbox) print("sadf") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())