I'm having an issue trying to animate a QPushButtons. I've a queue of buttons that once popped, I would like to animate from one color to another. I've recreated a minimum working example below:
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QHBoxLayout, QPushButton, QApplication, QWidget
from main import comboBox
app = QApplication([])
app.setStyle('Fusion')
window = QWidget()
def change_color():
anim = QtCore.QPropertyAnimation(changeButton, b"color")
anim.setDuration(1000)
anim.setStartValue(QtGui.QColor(255, 144, 0))
anim.setEndValue(QtGui.QColor(255, 255, 255))
anim.start()
hbox = QHBoxLayout()
hbox.addStretch(1)
changeButton = QPushButton()
changeButton.setText("change Grid")
hbox.addWidget((changeButton))
window.setLayout((hbox))
window.show()
app.exec()
changeButton.clicked.connect(lambda event: change_color())
When I go into the debug mode it shows that it's reaching each of the lines, however, it there is no color change happening. Am I doing something wrong here?
You have two problems.
The first is that you're connecting the signal after the
app.exec()call. That call starts the event loop, and, as such, it's blocking (nothing after that line will be processed until it returns), so you must move that before starting the event loop.Then, as the QPropertyAnimation documentation explains:
coloris not a Qt property for QPushButton (nor any of its base classes), in fact, if you look at the debug/terminal output for your program (after moving the signal connection as said above), you'll see the following:StdErr: QPropertyAnimation: you're trying to animate a non-existing property color of your QObjectA simple solution would be to use QVariantAnimation instead, and update the color in a function connected to the animation's
valueChangedsignal.The choice becomes the way you change color: if you're not using stylesheets for the button, the more appropriate way would be to use the button palette:
Note that I added the button argument (you should not use globals anyway), and also the
DeleteWhenStoppedflag tostart()in order to avoid unnecessary stacking of unused animations when they're finished.If, instead, you're using stylesheets, you need to override the button's stylesheet. Obviously, you have to be careful: the button shouldn't have any stylesheet set directly on it.
Note that a more appropriate approach would be to subclass the button and implement the animation directly on it. By doing that you can use a QPropertyAnimation by using a custom
pyqtProperty, but you will still need to manually set the color as above in the property setter. In this case, you can just have a single animation (possibly creating it in the__init__) and just update its start/end values.Alternatively, you can just call
updatein the setter, and override thepaintEvent()by using QStyle functions to draw the button primitive and label using the property value.