Reputation: 280
I'm trying to find a way to do a transition on a QML element, when a binding changes. Say you have a Text
element, with the text
property bound to something. What I want is when the data in the binding changes, the element fades out (Still displaying old data), switches and fades back in with the new data (the actual transition occurring while the element isn't visible.)
I've been searching everywhere for a way to do this but I can figure it out. I've tried using Qt Quick animations within QML, but the data itself changes before the animation runs, leaving the animation unnecessary. I've tried creating a custom QDeclarativeItem object that calls an animation within the QDeclarativeItem::paint()
but I can't figure out how to get it to actually run.
I should note here that I know my bindings are working fine as the displayed data changes, I just can't get these animations to run at the proper time.
Here is what I tried with QML:
Text {
id: focusText
text: somedata
Behavior on text {
SequentialAnimation {
NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 500 }
NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 500 }
}
}
}
And here is what I tried in implementing a custom QDeclarativeItem
:
// PAINTER
void AnimatedBinding::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
// Setup the pen
QPen pen(m_color, 2);
painter->setPen(pen);
painter->setOpacity(this->opacity());
// Draw the item
if (m_bindingType == QString("text")) {
QPropertyAnimation animation(this, "opacity");
animation.setDuration(1000);
animation.setStartValue(1);
if (drawn) {
animation.setStartValue(1);
animation.setEndValue(0);
animation.start();
} else drawn = true;
painter->drawText(boundingRect(), m_data.toString());
animation.setEndValue(0);
animation.start();
} else {
qCritical() << "Error unknown binding type!";
return;
}
}
But like I said, the animation that I start within the painter never actually fires.
Any tips? Anyone ever done this before? I've been banging my head on this for about a week.
Upvotes: 4
Views: 2036
Reputation: 7150
Necroposting but what's interesting is that OP was only one line away in its first try. The proper solution is to add an Animation with no explicit target to specify when you want the property being animated in a Behavior to actually change. For a string or a bool property, PropertyAction does the trick:
Behavior on text {
SequentialAnimation {
NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 500 }
PropertyAction {}
NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 500 }
}
}
No new object or property is being introduced, and the Behavior is on the text not on another property, making it clear when the animation is triggered.
Upvotes: 1
Reputation: 4858
How about doing it in qml only this ways :
eg. I have create a custom 'AnimatedText' type to have the fading in and fading out behavior on the text elements whenever text related to them changes.
File 1 : AnimatedText.qml
import QtQuick 1.0
Item
{
id: topParent
property string aText: ""
property string aTextColor: "black"
property int aTextFontSize: 10
property int aTextAnimationTime : 1000
Behavior on opacity { NumberAnimation { duration: aTextAnimationTime } }
onATextChanged:
{
topParent.opacity = 0
junkTimer.running = true
}
Timer
{
id: junkTimer
running: false
repeat: false
interval: aTextAnimationTime
onTriggered:
{
junkText.text = aText
topParent.opacity = 1
}
}
Text
{
id: junkText
anchors.centerIn: parent
text: ""
font.pixelSize: aTextFontSize
color: aTextColor
}
}
and in your main.qml
import QtQuick 1.0
Rectangle
{
id: topParent
width: 360
height: 360
AnimatedText
{
id: someText
anchors.centerIn: parent
aText: "Click Me to change!!!.."
aTextFontSize: 25
aTextColor: "green"
aTextAnimationTime: 500
}
MouseArea
{
anchors.fill: parent
onClicked:
{
someText.aText = "Some random junk"
}
}
}
Upvotes: 2