使用PyQt制作闪烁小部件

3

我只是希望QDialog内的一些元素闪烁(交替变换背景颜色)。

现在最好能够使用已经存在并封装了闪烁状态的东西,例如使用css3闪烁或者也许可以用QPropertyAnimation实现?

由于我没有找到任何有关该选项的好信息,因此我尝试了不太理想的解决方案:

来自对话框__init__的摘录:

self.timer = QTimer()
self.timer.timeout.connect(self.update_blinking)
self.timer.start(250)
self.last_blinked = None

并且

def update_blinking(self):
    self.frame.setStyleSheet(
        self.STYLE_BLINK_ON if self.blink else self.STYLE_BLINK_OFF)
    self.blink = not self.blink

其中,STYLE_BLINK_ONSTYLE_BLINK_OFF是一些指定背景颜色的CSS。这可以工作,但是:

  1. 我觉得它非常丑陋,感觉像90年代的代码。
  2. 它无法使用,因为频繁的样式更新会中断按钮点击。

关于第2点的解释:假设应该闪烁的小部件是一个框架。当框架内的按钮被单击时,在鼠标按钮释放之前,如果框架的样式更新,则不会发出clicked信号。

一个完全不同的解决方案,可以封装事物而不需要我手动启动计时器,当然更好。但是,如果有人能提出一个解决第二个问题的解决方案,我将不胜感激。

1个回答

7

一种方法是使用QPropertyAnimationQPropertyAnimation插值Qt属性 - 这个事实会导致困难:

1) 通过样式表更改外观 - 动画无法使用字符串,因为它们不能被插值。

2) 直接操作背景 - 背景颜色存储在QWidget.palette内部,它不是QProperty。 可能的解决方案是将背景颜色转换为小部件的属性:

class AnimatedWidget(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)

        color1 = QtGui.QColor(255, 0, 0)
        color2 = QtGui.QColor(0, 255, 0)

        self.color_anim = QtCore.QPropertyAnimation(self, 'backColor')
        self.color_anim.setStartValue(color1)
        self.color_anim.setKeyValueAt(0.5, color2)
        self.color_anim.setEndValue(color1)
        self.color_anim.setDuration(1000)
        self.color_anim.setLoopCount(-1)
        self.color_anim.start()

    def getBackColor(self):
        return self.palette().color(QtGui.QPalette.Background)

    def setBackColor(self, color):
        pal = self.palette()
        pal.setColor(QtGui.QPalette.Background, color)
        self.setPalette(pal)

    backColor = QtCore.pyqtProperty(QtGui.QColor, getBackColor, setBackColor)

另一种方法是处理 QStateMachine。它们能够操纵任何属性,不仅限于可插值的属性:
class StateWidget(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)

        style1 = "background-color: yellow"
        style2 = "background-color: black"

        # animation doesn't work for strings but provides an appropriate delay
        animation = QtCore.QPropertyAnimation(self, 'styleSheet')
        animation.setDuration(150)

        state1 = QtCore.QState()
        state2 = QtCore.QState()
        state1.assignProperty(self, 'styleSheet', style1)
        state2.assignProperty(self, 'styleSheet', style2)
        #              change a state after an animation has played
        #                               v
        state1.addTransition(state1.propertiesAssigned, state2)
        state2.addTransition(state2.propertiesAssigned, state1)

        self.machine = QtCore.QStateMachine()
        self.machine.addDefaultAnimation(animation)
        self.machine.addState(state1)
        self.machine.addState(state2)
        self.machine.setInitialState(state1)
        self.machine.start()

这些选项看起来好多了!我知道我在问题中没有具体说明,但我希望答案也提供一种将动画应用于现有小部件的方法,以便可以打开/关闭。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接