PDA

View Full Version : QML PropertyAnimation & StackView



scgrant327
12th May 2016, 15:00
Developing for Android. QT 5.6.

I have a StackView in my main.qml to load each of my sub-pages on demand. It's elegant, and works flawlessly. All my bindings allow data propagation without issues.

However, I have some C++ code that updates the QML with the user's location via property bindings. I have an Image type on one QML page that has a Glow and PropertyAnimation. This page is loaded via the StackView on app startup.


Glow {
id: statusGlow
anchors.fill: statusImage
radius: 16
samples: 33
spread: 0.85
color: appWin.statusGlowColor
source: statusImage
visible: appWin.statusGlowVisible
opacity: appWin.statusGlowOpacity
}
PropertyAnimation {
id: statusAnimation
target: statusGlow
property: "opacity"
from: 100
to: 0
duration: 500
running: appWin.statusAnimationRunning
}
Image {
id: statusImage
anchors.fill: parent
fillMode: Image.PreserveAspectFit
antialiasing: true
source: "status.png"
sourceSize.width: 715
sourceSize.height: 1543
smooth: false
}

As you can see, I am connecting the properties of the Glow and PropertyAnimation to variables in my main.qml (appWin). The C++ code updates those variables and calls a function in main.qml to 'enable' the Glow and PropertyAnimation:


function gpsUpdate2() {
if( !runningBackground ) {
statusGlowColor = "yellow";
statusGlowOpacity = 100;
statusGlowVisible = true;
statusAnimationRunning = true;
}
}

Problem is, this only works the FIRST time that 'gpsUpdate2' is called. On subsequent calls to 'gpsUpdate2', the Glow does not appear...Why?

john_god
12th May 2016, 17:31
I can tell you that in the function gpsUpdate2() you're assing values, so the binding are broke

scgrant327
12th May 2016, 17:46
I can tell you that in the function gpsUpdate2() you're assing values, so the binding are broke

I think you are incorrect on that.. the 'gpsUpdate2' function is IN my main.qml, where the variables reside. The BINDINGS are in MainWin.qml, which is loaded via StackView.

The variables are declared in main.qml:




property string statusGlowColor: "limegreen"
property bool statusGlowVisible: false
property int statusGlowOpacity: 100
property bool statusAnimationRunning: false

anda_skoa
13th May 2016, 09:55
Aside from your insistance on using hacks to interact with C++ there are two observations:

1) opacity is a value between 0 and 1, so 100 is a rather weird value
2) where in the code do you set statusAnimationRunning to false after you had set it to true?

Cheers,
_

scgrant327
13th May 2016, 13:49
Aside from your insistance on using hacks to interact with C++ there are two observations:
I'm not using any 'hacks' for interacting with C++... it's all pure property binding now. :confused:



1) opacity is a value between 0 and 1, so 100 is a rather weird value

Well, that does make some sense... but again... I've ALWAYS used 100 as the initial value, and it worked before StackView. Hmmmm. I'll make sure to use 1 instead of 100 and see if it appears different.



2) where in the code do you set statusAnimationRunning to false after you had set it to true?

Ahhhh... you are correct. I never reset the 'running' flag.... Odd thing is, I have NEVER reset that flag to false. And this USED to work before I starting using StackView. I was assuming that the 'running' flag was auto-set to false once the animation was completed.

anda_skoa
13th May 2016, 14:55
I'm not using any 'hacks' for interacting with C++... it's all pure property binding now. :confused:

You wrote "The C++ code updates those variables and calls a function in main.qml", so I assumed you meant calling a QML function from C++.
If you are no longer doing that hack you should be fine :)



Ahhhh... you are correct. I never reset the 'running' flag.... Odd thing is, I have NEVER reset that flag to false. And this USED to work before I starting using StackView. I was assuming that the 'running' flag was auto-set to false once the animation was completed.
The animation's own state is probably false, but since your property never is false ever again, it never changes when your function sets it to true, so the binding doesn't get reevaluated.

My suggestion would be to either reset the property in the animation's onStopped handler, or to remove the property and calling start() on the animation instead.

Cheers,
_

scgrant327
13th May 2016, 16:05
I'll try resetting the property in the onStopped handler... As I'm not sure how to call the 'start' method on an animation that exists on a page loaded by the StackView...

anda_skoa
14th May 2016, 11:27
As I'm not sure how to call the 'start' method on an animation that exists on a page loaded by the StackView...
Right.
Your main object could emit a signal and in the page element you could then use a Connection element to react to that.

Like you most likely already handle the signal from C++ that triggers the call to gpsUpdate2() (assuming you have, as you claim, moved away from the hack of calling QML functions from C++).

Cheers,
_

scgrant327
16th May 2016, 14:06
Thanks again Anda. Resetting via the onStopped handler worked perfectly.

--Sam