Qt 中的动画绑定更改

问题描述 投票:0回答:2

我正在尝试找到一种在绑定更改时在 QML 元素上进行转换的方法。假设您有一个

Text
元素,并且
text
属性绑定到某个东西。我想要的是,当绑定中的数据发生变化时,元素淡出(仍然显示旧数据),切换并淡入新数据(实际转换发生在元素不可见时。)

我一直在到处寻找一种方法来做到这一点,但我能弄清楚。我尝试过在 QML 中使用 Qt Quick 动画,但数据本身在动画运行之前发生了变化,使得动画变得不必要。我尝试创建一个自定义 QDeclarativeItem 对象,该对象在

QDeclarativeItem::paint()
中调用动画,但我不知道如何让它实际运行。

我应该在这里指出,我知道随着显示的数据变化,我的绑定工作正常,我只是无法让这些动画在适当的时间运行。

这是我用 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 }
         }
     }
}

这是我尝试实现自定义的

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;
    }
}

但就像我说的,我在画家中启动的动画从未真正触发。

有什么建议吗?以前有人这样做过吗?我已经为此苦恼了大约一周。

c++ qt qml
2个回答
2
投票

仅通过这种方式在 qml 中进行操作怎么样:

  1. 定义您自己类型的自定义元素,其行为方式符合您想要的方式。
  2. 使用此元素代替传统元素进行动画。

例如。我创建了一个自定义“AnimatedText”类型,以便在与文本相关的文本发生变化时在文本元素上具有淡入和淡出行为。

文件 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
    }
}

在你的 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"
        }
    }
}

0
投票

Necroposting,但有趣的是,OP 在第一次尝试中只差一行。 正确的解决方案是添加一个没有明确目标的动画来指定您希望行为中的动画属性实际发生变化的时间。对于字符串或布尔属性,PropertyAction 可以解决这个问题:

Behavior on text {
     SequentialAnimation {
         NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 500 }
         PropertyAction {}
         NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 500 }
     }
 }

没有引入新的对象或属性,并且行为位于文本上而不是其他属性上,这使得动画何时触发变得清晰。

© www.soinside.com 2019 - 2024. All rights reserved.