видимое свойство в PyQt Animation Framework и State Machine

Извините за мой ломаный английский.

Я использую конечный автомат с анимацией. Я хочу реализовать эффект затухания/исчезновения.

state1: opacity = 0 visible = False

state2: opactiy = 1 visible = True

state1 -> state2: переместите виджет снизу вверх, сначала установите для свойства «visible» значение «True», а затем установите «opactiy» от 0,0 до 1,0 за 5 секунд.

state2 --> state1: переместите виджет сверху вниз, его "непрозрачность" изменится с 1,0 на 0,0 за 5 секунд, а затем установите для свойства "видимого" виджета значение False.

Но проблема в том, что когда state2 в state1, он всегда сначала устанавливает для свойства "visible" значение False, поэтому я вижу, что виджет исчезает без эффекта затухания, даже если я использую QSequentialAnimationGroup и сначала устанавливаю opactiy_animation.

Как получить эффект затухания?

Код:

self.group_p = QtCore.QParallelAnimationGroup()   
self.group_s = QtCore.QSequentialAnimationGroup()
self.group_sr = QtCore.QSequentialAnimationGroup()

goe = QtGui.QGraphicsOpacityEffect()
self.label_arrow.setGraphicsEffect(goe)
animation_o = QtCore.QPropertyAnimation(goe, "opacity")             
animation_g = QtCore.QPropertyAnimation(self.label_arrow, "geometry")
animation_v = QtCore.QPropertyAnimation(self.label_arrow, "visible")

animation_g.setDuration(5000)
animation_g.setEasingCurve(QEasingCurve.OutBounce)
animation_o.setDuration(5000)

self.group_p.addAnimation(animation_g)
self.group_p.addAnimation(animation_o)                                                                     

self.group_s.addAnimation(self.group_p)
self.group_s.addAnimation(animation_v)

self.group_sr.addAnimation(animation_v)
self.group_sr.addAnimation(self.group_p)

self.machine = QtCore.QStateMachine()
state1 = QState(self.machine)
state2 = QState(self.machine)
self.machine.setInitialState(state1)

state1.assignProperty(self.label_arrow, "geometry", QtCore.QRect(self.label_arrow.x(),\
                        self.label_arrow.y()+100, self.label_arrow.width(), self.label_arrow.height()))
state1.assignProperty(self.label_arrow, "visible", False)
state1.assignProperty(goe, "opacity", 0.5)                                      

state2.assignProperty(self.label_arrow, "geometry", self.label_arrow.geometry())
state2.assignProperty(self.label_arrow, "visible", True)
state2.assignProperty(goe, "opacity", 1)                         

transition = state1.addTransition(self.sig_arrow_animate, state2)
transition.addAnimation(self.group_sr)                            

transition2 = state2.addTransition(self.sig_arrow_animate, state1)
transition2.addAnimation(self.group_s) # set visible to False first!
self.machine.start()

person lSaint    schedule 05.09.2011    source источник


Ответы (1)


Вы не можете анимировать свойство visible, так как bool не поддерживается для анимации. Вы должны удалить его из анимации и использовать только assignProperty для этого свойства.

Согласно документации конечное значение также присваивается QState после окончания анимации. Вот почему, даже если анимация не работает, конечное значение правильное ((edit), и этот абзац не очень полезен, так как анимация для bool не выполняется, и поэтому состояние изменяется немедленно ).

Вам нужно разделить state1 на 2 подсостояния, первое со свойствами "геометрия" и "непрозрачность", а второе, вызванное сигналом propertiesAssigned(), который испускается, когда все анимации для текущего состояния завершены, со свойством " видимое" свойство.

state1_1 = QState(state1)
state1_2 = QState(state1)
state1.setInitialState(state1_1)

state1_1.assignProperty(self.label_arrow, "geometry", QtCore.QRect(self.label_arrow.x(),\
                        self.label_arrow.y()+100, self.label_arrow.width(), self.label_arrow.height()))
state1_1.assignProperty(goe, "opacity", 0.5) 

state1_2.assignProperty(self.label_arrow, "visible", False)
state1_1.addTransition(state1_1.propertiesAssigned, state1_2)
...
person alexisdm    schedule 05.09.2011
comment
Спасибо. Я знаю, что вы имеете в виду, я удаляю анимацию_v и использую только assignProperty для видимого свойства. Но работает так же. При изменении состояния сначала присваивается свойство visible, а не после окончания анимации. Я что-то пропустил? - person lSaint; 06.09.2011
comment
@lSaint Я неправильно понял, проблема была в том, что я отредактировал свой ответ, чтобы предоставить решение. - person alexisdm; 06.09.2011
comment
Здорово! Это Работа. Еще раз спасибо. Кстати, нужно изменить QFinalState на QState, потому что объект 'QFinalState' не имеет атрибута assignProperty :) - person lSaint; 06.09.2011