Bizarre QML animation bug
-
I have just spent a couple of evenings hunting down a bug that's so strange I'm not sure I believe it. I thought I'd bring it up here first before raising a bug report because I don't have time to make a minimal project to reproduce it at the moment.
I've written a 2D scrolling game using QGraphicsView and the menus are built with QML. The interface between the QML and the C++ parts is just signals and slots. Certain signals trigger the QGraphicsView based window to be raised above the QML viewer and others the reverse. To smooth things out a bit I have a transition animation in QML which fakes fading the game screen in (it just fades a screenshot of the start position in) before the real thing appears over the top - a dirty hack but it was much quicker to write than fading the entire graphics view in and there was a CAI contest deadline to meet. :)
The transition takes the menu from a level selection state to a paused state. You don't see the end of the transition and the actual paused screen because the graphics view is raised over the top first. There's one other transition animation in the QML for going from the paused state back to the root state of the menu.
Here are the transitions:
@transitions: [
Transition {
from: "LevelSelect"; to: "Paused"
SequentialAnimation {
NumberAnimation { target: start; property: "opacity"; to: 0.0; duration: 1000 }
PropertyAnimation { target: start; property: "visible"; to: false; duration: 1 }
PropertyAnimation { target: fakelevel; property: "visible"; to: true; duration: 1 }
PropertyAnimation { target: fakelevel; property: "opacity"; to: 1.0; duration: 1000 }
PropertyAnimation { target: fakelevel; property: "visible"; to: false; duration: 1 }
PropertyAnimation { target: fakelevel; property: "opacity"; to: 0.0; duration: 1 }
PropertyAnimation { target: pausemode; property: "visible"; to: true; duration: 1 }
NumberAnimation { target: start; property: "opacity"; to: 1.0; duration: 1 }
}
},
Transition {
from: "Paused"; to: ''
SequentialAnimation {
NumberAnimation { target: pausemode; property: "opacity"; to: 0.0; duration: 1000 }
PropertyAnimation { target: menu; property: "visible"; to: true; duration: 1 }
PropertyAnimation { target: pausemode; property: "visible"; to: false; duration: 1 }
PropertyAnimation { target: menu; property: "opacity"; from: 0.0; to: 1.0; duration: 300 }
NumberAnimation { target: pausemode; property: "opacity"; to: 1.0; duration: 1 }
}
}
]
@
Here's where it gets weird. If I increase the duration 300 by much in the second transition then when I leave the game and go to the paused screen after starting the level 2 or 3 times (sometimes more than 2 but almost never more than 3) then I just get a completely blank screen and can do nothing at all. If I switch the PropertyAnimation and the NumberAnimation around at the end of the sequence then I can increase the duration to 1000 (which is where I want it) and everything works fine.It seems as if when the animation gets long, the declarative engine just forgets to do the last opacity switch in the transition animation! I might have expected this bug if it was the animation which completes in the background behind the QGraphicsView, but it's not - it's the one that completes in full view every time.
Has anyone else seen anything like this or have any idea why it might happen?
-
Hi,
I'm not sure if this will actually help fix the issue, but have you tried using "PropertyAction":http://doc.qt.nokia.com/4.7/qml-propertyaction.html for the immediate changes rather than animations with duration of 1?
Regards,
Michael -
Thanks - clearly I didn't read the documentation thoroughly enough. :)
Purely in the spirit of improving the docs, it would be easier to find the right thing if the PropertyAnimation documentation mentioned PropertyAction for immediate property changes.
Actually, looking at it again I can see I was in a hurry because I've used PropertyAnimation and NumberAnimation almost randomly - completely independent of whether the property is actually a number!
I'll give PropertyAction a try and see if it makes any difference.
It's not a major issue because I get what I wanted by just switching the last two items in the sequence.