PyQt 动画框架和状态机中的可见属性

发布于 2024-12-02 18:10:42 字数 2318 浏览 1 评论 0原文

抱歉我的英语很蹩脚。

我正在使用带有动画的状态机。我想实现淡出/淡入效果。

状态1: 不透明度 = 0 可见=假

状态2: 不透明度 = 1 可见 = True

state1 -->状态2: 将小部件从下到上移动,先将“visible”属性设置为 True,然后设置 “opactiy”在 5 秒内从 0.0 到 1.0。

状态2 -->状态1: 将小部件从上到下移动,其“opactiy”在 5 秒内从 1.0 变为 0.0,然后将小部件的“visible”属性设置为 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()

Sorry about my broken English.

I am using a state machine with animations.I want to implement the fade out/in effect.

state1:
opactiy = 0
visible = False

state2:
opactiy = 1
visible = True

state1 --> state2:
Move the widget from bottom to top, set "visible" property to True first, and then set
"opactiy" from 0.0 to 1.0 in 5 seconds.

state2 --> state1:
Move the widget from top to bottom, its "opactiy" is from 1.0 to 0.0 in 5 seconds, and then set the widget's "visible" property to False.

But the problem is, when state2 to state1, it always set the "visible" property to False first, so what i see is the widget disappear without fade out effect, even if i use QSequentialAnimationGroup and set opactiy_animation first.

How do i get the fade out effect?

The Code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红墙和绿瓦 2024-12-09 18:10:42

您无法为 visible 属性设置动画,因为 bool 不是动画支持的类型。您应该将其从动画中删除,并仅对该属性使用assignProperty

根据文档,结束值也在动画结束后由QState分配。这就是为什么即使动画不起作用,最终值也是正确的((编辑)并且该段落不是很有帮助,因为 bool 的动画没有执行因此状态立即改变)。

您需要将 state1 分为 2 个子状态,第一个具有“geometry”和“opacity”属性,第二个由信号 propertiesAssigned() 触发当当前状态的所有动画完成时发出,具有“visible”属性。

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

You can't animate the visible property, because bool isn't a supported type for animations. You should remove it from the animation, and use only assignProperty for that property.

According to the documentation, the end value is also assigned by the QState after the end of the animation. That's why even though the animation doesn't work the end value is correct ((edit) and that paragraph was not very helpful, since the animation for the bool is not executed and so the state is changed immediately).

You need to divide state1 in 2 sub-states, the first with the "geometry" and "opacity" properties, and the second, triggered by the signal propertiesAssigned() that is emitted when all the animations for the current state are finished, with the "visible" property.

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)
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文