Как обновить AnimationGroup без создания новой AnimationGroup каждый раз? - PullRequest
0 голосов
/ 22 апреля 2020

Я хочу запустить 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: упакованный объект C / C ++ типа QVariantAnimation был удален

Я не могу постоянно создавать новую группу.

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 Ответ

1 голос
/ 22 апреля 2020

Из того, что я могу сделать вывод, вы хотите, чтобы нажатый элемент перемещался вниз, и если какой-либо элемент находился в нижнем положении, он должен вернуться в свое положение. Если так, то мой ответ должен сработать.

Вы не должны использовать метод clear, так как он удаляет и удаляет анимацию, вместо этого используйте takeAnimation(0), пока нет анимаций, и просто добавьте новые анимации, но эти логи c должно быть не внутри "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_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...