Почему я не могу добавить анимаций через for?

Мой код

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(100, 300)

        lay = QtWidgets.QVBoxLayout(self)

        self.radio = QtWidgets.QRadioButton()

        self.label_1 = QtWidgets.QLabel()
        self.label_1.setText('but-{}'.format(1))

        self.label_2 = QtWidgets.QLabel()
        self.label_2.setText('but-{}'.format(2))

        self.label_3 = QtWidgets.QLabel()
        self.label_3.setText('but-{}'.format(3))

        lay.addWidget(self.label_1)
        lay.addWidget(self.label_2)
        lay.addWidget(self.label_3)


        lay.addWidget(self.radio)


    def color_ch(self, color='', type=None):
        if type == 0 :
            wid = self.label_1
        elif type == 1 :
            wid = self.label_2
        elif type == 2 :
            wid = self.label_3
        wid.setStyleSheet('background:{}'.format(color.name()))




class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.group = QtCore.QSequentialAnimationGroup(self)

        arr_val  = [
            ['white','black'],
            ['red','blue'],
            ['green','yellow'],
        ]
        an = []
        self.widget = Rad(self.group, 200, self)
        self.widget.radio.toggled.connect(self.on)
        for id,val in enumerate(arr_val):
            ani = QtCore.QVariantAnimation(duration=1000, startValue=QtGui.QColor(val[0]), endValue=QtGui.QColor(val[1])  )
            an.append(ani)
            an[id].valueChanged.connect(lambda color : self.widget.color_ch(color, type=id))
            self.group.addAnimation(an[id])


    def on(self):
        self.group.start()

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

Я решил попробовать вместо того что бы писать по нескольку раз QVariantAnimation пропустить его через for но почему-то он не красит поочередно все лайблы а только последний.

Единственный способ который я знаю это написать так:

    for id,val in enumerate(arr_val):
        ani = QtCore.QVariantAnimation(duration=1000, startValue=QtGui.QColor(val[0]), endValue=QtGui.QColor(val[1])  )
        an.append(ani)
    an[0].valueChanged.connect(lambda color : self.widget.color_ch(color, type=0))
    an[1].valueChanged.connect(lambda color : self.widget.color_ch(color, type=1))
    an[2].valueChanged.connect(lambda color : self.widget.color_ch(color, type=2))
    for id,val in enumerate(arr_val):
        self.group.addAnimation(an[id])

Но приходится писать 4 лишних строки кода. Можно ли это как нибудь исправить ?

Как я понял type постоянно выводит последнее число. Можно ли в цикле for передать остальные значения а не только последнее ?


Ответы (1 шт):

Автор решения: S. Nick

замените

an[id].valueChanged.connect(lambda color : self.widget.color_ch(color, type=id))       

на

an[id].valueChanged.connect(lambda color, type=id : self.widget.color_ch(color, type))

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(100, 300)

        lay = QtWidgets.QVBoxLayout(self)

        self.radio = QtWidgets.QRadioButton()

        self.label_1 = QtWidgets.QLabel()
        self.label_1.setText('but-{}'.format(1))
        self.label_2 = QtWidgets.QLabel()
        self.label_2.setText('but-{}'.format(2))
        self.label_3 = QtWidgets.QLabel()
        self.label_3.setText('but-{}'.format(3))

        lay.addWidget(self.label_1)
        lay.addWidget(self.label_2)
        lay.addWidget(self.label_3)
        lay.addWidget(self.radio)

    def color_ch(self, color='', type=None):
        if type == 0 :
            wid = self.label_1
        elif type == 1 :
            wid = self.label_2
        elif type == 2 :
            wid = self.label_3
        wid.setStyleSheet('background:{}'.format(color.name()))


class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.group = QtCore.QSequentialAnimationGroup(self)

        arr_val  = [
            ['white','black'],
            ['red','blue'],
            ['green','yellow'],
        ]
        an = []
        self.widget = Rad(self.group, 200, self)
        self.widget.radio.toggled.connect(self.on)
        for id, val in enumerate(arr_val):
            ani = QtCore.QVariantAnimation(duration=1000, startValue=QtGui.QColor(val[0]), endValue=QtGui.QColor(val[1])  )
            an.append(ani)
#            an[id].valueChanged.connect(lambda color : self.widget.color_ch(color, type=id))       # ---
            an[id].valueChanged.connect(lambda color, type=id : self.widget.color_ch(color, type))  # +++

            self.group.addAnimation(an[id])


    def on(self):
        self.group.start()

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

введите сюда описание изображения

→ Ссылка