How to animate the background color of a QPushButton(change button color dynamically)

1.3k Views Asked by At

I am trying to make a pushButton in pyqt5 Python, change background color - shades, etc. from a light green, to grenn, and then, to dark green.

I have tryied some code, but nothing.

Here's my code:

    def colorChange(self,button):     
        self.anim = QPropertyAnimation(button, b"color")
        self.anim.setDuration(2500)
        self.anim.setLoopCount(2)
        self.anim.setStartValue(QColor(0, 0, 0))
        self.anim.setEndValue(QColor(255, 255, 255))  
        self.anim.start()  

    def eventFilter(self, object, event):
        
        print(int(time.time()-self.first))
        if event.type() == QtCore.QEvent.Enter:
            if self.stackedWidget.currentIndex()==0:
                self.pagelabel1.deleteLater() 
                print("Mouse is over the label")
                self.stop = True
                print('program stop is', self.stop)

                pick=random.randrange(0,2)
                print('random:',pick)
                pick=0
                if pick==0:
                    #self.doAnimation(self.right1)
                    self.colorChange(self.right1)
                    
                    #self.right1.setStyleSheet("background-color: lightgreen")
                    self.right1.clicked.connect(self.nextpage)
                else:
                    #self.doAnimation(self.left1)
                    self.colorChange(self.left1)
                    
                    #self.left1.setStyleSheet("background-color: lightgreen")
                    self.left1.clicked.connect(self.nextpage)

I want the eventFilter to starts the animation, and the animation will be the color change of the button.

1

There are 1 best solutions below

0
On

Buttons (and other widgets) don't have a qproperty called color so you should not use QPropertyAnimation, in this case you should use Qt StyleSheet to change the color so you should use a QVariantAnimation:

import functools
from PyQt5 import QtCore, QtGui, QtWidgets


def helper_function(widget, color):
    widget.setStyleSheet("background-color: {}".format(color.name()))


def apply_color_animation(widget, start_color, end_color, duration=1000):
    anim = QtCore.QVariantAnimation(
        widget,
        duration=duration,
        startValue=start_color,
        endValue=end_color,
        loopCount=2,
    )
    anim.valueChanged.connect(functools.partial(helper_function, widget))
    anim.start(QtCore.QAbstractAnimation.DeleteWhenStopped)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.button = QtWidgets.QPushButton()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.button)

        timer = QtCore.QTimer(self, interval=5 * 1000)
        timer.timeout.connect(self.handle_timeout)
        timer.start()
        self.handle_timeout()

    def handle_timeout(self):
        apply_color_animation(
            self.button,
            QtGui.QColor("lightgreen"),
            QtGui.QColor("darkgreen"),
            duration=2500,
        )


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("fusion")
    w = Widget()
    w.show()
    sys.exit(app.exec_())