我有一个问题,试图动画一个QPushButtons。我有一个按钮队列,一旦弹出,我想动画从一种颜色到另一种。我在下面重新创建了一个最低工作示例:
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())
当我进入调试模式时,它显示它到达了每一行,但是没有发生任何颜色变化。我在这里做错什么了吗?
发布于 2022-10-24 17:54:49
你有两个问题。
第一个是在app.exec()
调用之后连接信号。该调用启动事件循环,因此它处于阻塞状态(在该行返回之前不会进行任何处理),因此必须在启动事件循环之前将其移动。
QPropertyAnimation在Qt 属性上进行插值。
color
不是QPushButton的Qt属性(也不是它的任何基类),实际上,如果您查看程序的调试/终端输出(在移动了上面提到的信号连接之后),您将看到以下内容:
StdErr: QPropertyAnimation: you're trying to animate a non-existing property color of your QObject
一个简单的解决方案是使用QVariantAnimation,并在连接到动画的valueChanged
信号的函数中更新颜色。
def change_color():
def updateColor(color):
# ... change the color
anim = QtCore.QVariantAnimation(changeButton)
anim.setDuration(1000)
anim.setStartValue(QtGui.QColor(255, 144, 0))
anim.setEndValue(QtGui.QColor(255, 255, 255))
anim.valueChanged.connect(updateColor)
anim.start()
# ...
changeButton.clicked.connect(change_color)
选择变成了更改颜色的方式:,如果您不对按钮使用样式表,则更合适的方法是使用按钮调色板:
def change_color(button):
def updateColor(color):
palette.setColor(role, color)
button.setPalette(palette)
palette = button.palette()
role = button.foregroundRole()
anim = QtCore.QVariantAnimation(button)
anim.setDuration(1000)
anim.setStartValue(QtGui.QColor(255, 144, 0))
anim.setEndValue(QtGui.QColor(255, 255, 255))
anim.valueChanged.connect(updateColor)
anim.start(anim.DeleteWhenStopped)
# ...
changeButton.clicked.connect(lambda: change_color(changeButton))
请注意,我添加了按钮参数(无论如何不应该使用globals ),还向start()
添加了start()
标志,以避免在未使用的动画完成时不必要地堆叠。
如果使用样式表,则需要重写按钮的样式表。显然,您必须小心:按钮上不应该直接设置任何样式表。
def change_color(button):
def updateColor(color):
button.setStyleSheet('color: {}'.format(color.name()))
# ...
请注意,更合适的方法是将按钮子类并直接在其上实现动画。通过这样做,您可以通过使用自定义的QPropertyAnimation来使用pyqtProperty
,但是仍然需要手动设置属性设置器中的颜色。在这种情况下,您可以只有一个动画(可能在__init__
中创建它),只需更新它的开始/结束值。
或者,您只需在setter中调用update
,并通过使用QStyle函数绘制按钮原语并使用属性值进行标签来覆盖paintEvent()
。
https://stackoverflow.com/questions/74184099
复制相似问题