如何更新AnimationGroup而不每次都创建新的AnimationGroup?

时间:2020-04-22 12:17:52

标签: python pyqt pyqt5

我想用不同的动画运行一个AnimationGroup。 但是问题在于函数clear()

    self.group = QtCore.QSequentialAnimationGroup(self)
def anim(self):
    if X == True:
        self.group.addAnimation(self.animation_1)
        self.group.addAnimation(self.animation_2)
    elif X == False:
        self.group.addAnimation(self.animation_3)
        self.group.addAnimation(self.animation_4)
    self.group.start()
    self.group.clear()

显示错误

RuntimeError:QVariantAnimation类型的包装的C / C ++对象已被删除

我无法不断创建新的网上论坛。

def anim(self):
    self.group = QtCore.QSequentialAnimationGroup(self)
    if X == True:
        self.group.addAnimation(self.animation_1)
        self.group.addAnimation(self.animation_2)
    elif X == False:
        self.group.addAnimation(self.animation_3)
        self.group.addAnimation(self.animation_4)
    self.group.start()
    self.group.clear()

我尝试使用removeAnimation

import sys
from PyQt5 import QtWidgets, QtGui, QtCore

class Rad(QtWidgets.QWidget):
    def __init__(self, group, pos, parent=None):
        super(Rad,  self).__init__(parent)
        self.resize(50, 50)
        lay = QtWidgets.QVBoxLayout(self)
        self.radio = QtWidgets.QRadioButton()
        self.label = QtWidgets.QLabel()
        self.label.setText('but-{}'.format(pos))
        self.group = group
        self.pos = pos
        lay.addWidget(self.radio)
        lay.addWidget(self.label)
        self.radio.toggled.connect(self.fun)
        self.animation = QtCore.QVariantAnimation() 
        self.animation.setDuration(1000)  
        self.animation.valueChanged.connect(self.value)
        self.animation.setStartValue(100)
        self.animation.setEndValue(0)
        self.can = False
    def value(self, val):
        self.move(self.pos, val)
    def fun(self):
        self.animation.setStartValue(
            100
            if not self.can 
            else 0
        )
        self.animation.setEndValue(
            0
            if not self.can 
            else 100
        )
        if self.group.animationAt(1) == None :
            print("Bad")
        else :
            print("Good")
            self.group.removeAnimation(self.group.animationAt(0))
        self.group.addAnimation(self.animation)
        self.group.start()
        self.can = not self.can

class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.group = QtCore.QSequentialAnimationGroup(self)
        self.buts = QtWidgets.QButtonGroup(self, exclusive=True)
        wid_1 = Rad(self.group,   200, self)
        wid_2 = Rad(self.group,  100, self)
        wid_3 = Rad(self.group,  0, self)
        self.buts.addButton(wid_1.radio, 0)
        self.buts.addButton(wid_2.radio,1)
        self.buts.addButton(wid_3.radio, 2)
        wid_1.setStyleSheet('background:brown;')
        wid_2.setStyleSheet('background:yellow;')
        wid_3.setStyleSheet('background:green;')

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = Test()
    w.resize(500, 500)
    w.show()
    sys.exit(app.exec_())

现在动画变得清晰了

enter image description here

在控制台输出中

QAnimationGroup :: animationAt:索引超出范围

1 个答案:

答案 0 :(得分:1)

根据我的推论,您希望按下的项目向下移动,如果任何项目处于较低位置,则它必须返回其位置。如果是这样,那么我的答案应该起作用。

您不应使用clear方法,因为该方法会删除和删除动画,而应使用takeAnimation(0)直到没有动画,然后添加新动画,但该逻辑不应放在“ Rad”中,而应放在测试类:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore


class Rad(QtWidgets.QWidget):
    def __init__(self, text, parent=None):
        super(Rad, self).__init__(parent)
        self.resize(50, 50)
        self.radio = QtWidgets.QRadioButton()
        self.label = QtWidgets.QLabel()
        self.label.setText(text)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.radio)
        lay.addWidget(self.label)

        self.animation = QtCore.QVariantAnimation()
        self.animation.setDuration(1000)
        self.animation.valueChanged.connect(self.on_value_changed)
        self.animation.setStartValue(100)
        self.animation.setEndValue(0)

    @QtCore.pyqtSlot("QVariant")
    def on_value_changed(self, val):
        pos = self.pos()
        pos.setY(val)
        self.move(pos)

    def swap_values(self):
        self.animation.blockSignals(True)
        start_value = self.animation.startValue()
        end_value = self.animation.endValue()
        self.animation.setStartValue(end_value)
        self.animation.setEndValue(start_value)
        self.animation.blockSignals(False)


class Test(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.buts = QtWidgets.QButtonGroup(self, exclusive=True)
        wid_1 = Rad("but-200", self)
        wid_1.setStyleSheet("background:brown;")
        wid_1.move(200, 0)

        wid_2 = Rad("but-100", self)
        wid_2.setStyleSheet("background:yellow;")
        wid_2.move(100, 0)

        wid_3 = Rad("but-0", self)
        wid_3.setStyleSheet("background:green;")
        wid_3.move(0, 0)

        self.buts.addButton(wid_1.radio, 0)
        self.buts.addButton(wid_2.radio, 1)
        self.buts.addButton(wid_3.radio, 2)

        self.buts.buttonToggled.connect(self.on_button_toggled)

        self.group = QtCore.QSequentialAnimationGroup(self)

        self.last_widget = None

    @QtCore.pyqtSlot(QtWidgets.QAbstractButton, bool)
    def on_button_toggled(self, button, state):
        if state:
            wid = button.parent()
            if self.group.animationCount() > 0:
                self.group.takeAnimation(0)
            if isinstance(self.last_widget, Rad):
                self.last_widget.swap_values()
                self.group.addAnimation(self.last_widget.animation)
            wid.swap_values()
            self.group.addAnimation(wid.animation)
            self.group.start()
            self.last_widget = wid


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Test()
    w.resize(500, 500)
    w.show()
    sys.exit(app.exec_())