使用 PyQt 闪烁小部件 [英] Blinking Widget with PyQt

查看:68
本文介绍了使用 PyQt 闪烁小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想让 QDialog 中的一些元素闪烁(改变背景颜色).

I simply want some elements inside a QDialog to be blinking (altering background color).

现在最好我希望能够使用已经存在的东西并封装闪烁状态,即使用 css3 闪烁或者使用 QPropertyAnimation 可能?

Now preferably I'd like to be able to use something that already exists and encapsulates the blinking state, i.e. blinking with css3 or maybe it is possible with QPropertyAnimation?

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

Since I didn't find any nice info on that option I tried the less optimal solution:

摘自对话__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.那行得通,但是

where STYLE_BLINK_ON and STYLE_BLINK_OFF are some css specifying the background colors. That works but

  1. 我觉得它超级难看,感觉就像 90 年代的代码
  2. 它不可用,因为频繁的样式更新会中断按钮点击.

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

Explanation for 2.: Assume the widget that should be blinking is a frame. When a button inside that frame is clicked, the clicked signal isn't emitted if a style-update of the frame occurs before the mouse-button is released.

一个完全不同的解决方案,它封装了一些东西,不需要我手动启动一个计时器,当然是首选.但如果有人至少提出解决第 2 点的解决方案,我将不胜感激.

A completely different solution that encapsulates things and doesn't require me to manually start a timer would of course be preferred. But I would be grateful if someone at least came up with a solution which solves point 2.

推荐答案

一种方法是使用 QPropertyAnimation.QPropertyAnimation 对 Qt 属性进行插值 - 这个事实造成了困难:

The one way is to use QPropertyAnimation. QPropertyAnimation interpolates over Qt properties - this fact causes difficulties:

1) 通过样式表更改外观 -- 动画不能与字符串一起使用,因为它们不可插入.

1) Change appearance via style sheet -- animation cannot work with strings, because they're not interpolable.

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

2) Manipulate background directly -- background color is stored deep inside QWidget.palette, it's not a QProperty. The possible solution is to transform background color into a widget's property:

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.他们能够操纵任何属性,而不仅仅是可插入的属性:

The other approach is dealing with QStateMachines. They're able to manipulate any properties, not only interpolable ones:

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

这篇关于使用 PyQt 闪烁小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆