【问题标题】:Blinking Widget with PyQt使用 PyQt 闪烁小部件
【发布时间】:2015-08-03 11:58:27
【问题描述】:

我只是想让 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 信号。

当然,一个完全不同的解决方案可以封装事物并且不需要我手动启动计时器。 但如果有人至少想出了解决第 2 点的解决方案,我将不胜感激。

【问题讨论】:

    标签: python qt pyqt


    【解决方案1】:

    一种方法是使用QPropertyAnimationQPropertyAnimation interpolates over Qt properties - 这个事实造成了困难:

    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)
    

    另一种方法是处理QStateMachines。他们能够操纵任何属性,而不仅仅是可插值的:

    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()
    

    【讨论】:

    • 这些选项看起来好多了!我知道我在我的问题中没有具体说明它,但我想要它,如果答案还提供了一种将动画应用于现有小部件的方法,以便可以打开/关闭它
    猜你喜欢
    • 1970-01-01
    • 2015-04-08
    • 2015-05-29
    • 2021-04-11
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 2012-06-18
    相关资源
    最近更新 更多