Draft: Animations
A guide about QtQuick animators, animations and transitions.
Instant animations
Sometimes animations have to be disabled. This may be done for accessibility purposes, to conserve battery in Power Saving mode, or simply to honor user preferences. So, how to disable an animation in QtQuick?
In QtQuick it is rather inconvenient to use conditionals for components; for example, no one writes like this:
Behavior on x {
// Don't do this at home!
animation: Settings.disableAnimations ? null : myAnimation
}
NumberAnimation {
id: myAnimation
duration: 1000
}
Full code available here.
Animations are hard-wired to their Behavior the moment they are assigned. Trying to reset Behavior's animation back to null would throw an error "QML Behavior: Cannot change the animation assigned to a Behavior." (actually, it would fail only if/after the animation has been started at least once: you can reassign all you want before the Behavior is triggered — this is due to the animation property being "deferred", so its binding will only evaluate on first write to the intercepted property).
Being a property interceptor, Behavior as a whole can not be conditional either. In fact, whenever a property interceptor is present on a component, the QML runtime would create an extra meta-object subtype with overridden setters for the intercepted properties (this holds true both for regular and attached objects).
So instead it might be tempting to set animation duration to zero:
Behavior on x {
NumberAnimation {
// Don't do this at home either
duration: Settings.disableAnimations ? 0 : 1000
}
}
This may not work in some cases, because animations tend to be lazy (or buggy): they treat zero duration as being disabled, and won't do anything. So, properties may get stuck at starting (from) values, and event triggers never occur (so called "user control", like runningChanged(), stopped() signals etc.). For example, see https://invent.kde.org/plasma/libplasma/-/merge_requests/1077.
Disable Behavior completely:
Behavior {
enabled: !Settings.disableAnimations
}