problem with QPropertyAnimation in Qt

2019-08-24 15:17发布

问题:

i have a problem with QPropertyAnimation in Qt

my code:

QString my_text = "Hello Animation";
        ui->textBrowser->setText((quote_text));
        ui->textBrowser->show();
        QPropertyAnimation animation2(ui->textBrowser,"geometry");
        animation2.setDuration(1000);
        animation2.setStartValue(QRect(10,220/4,1,1));
        animation2.setEndValue(QRect(10,220,201,71));
        animation2.setEasingCurve(QEasingCurve::OutBounce);
        animation2.start();

till now it seems very good , but the problem is that i can see this animation only when i show a message box after it .

        QMessageBox m;
        m.setGeometry(QRect(100,180,100,50));
        m.setText("close quote");
        m.show();
        m.exec();

when i remove the code of this message box , i can't see the animation anymore. the functionality of the program doesn't require showing this MessageBox at all. Can anybody help?

回答1:

Maybe it is an update problem. Could you try to connect the valueChanged() signal of QPropertyAnimation to an update() call in the GUI?



回答2:

My guess is that the code for the animation that you present is inside a larger chunk of code where the control doesn't get back to the event loop (or the event loop hasn't started yet). This means that when the MessageBox's exec function is called, an event loop starts operating again, and the animation starts. If you were to dismiss the message box in the middle of the animation, it would probably freeze at that point, as well.



回答3:

animation2 is declared as a local variable. When the enclosing function exits, it is no longer in scope and is deleted. The animation never runs as it does not exist when Qt returns to the event loop and, as noted in the QAbstractAnimation documentation (QPropertyAnimation inherits QAbstractAnimation), for QPropertyAnmiation to execute, it must exist when Qt returns to the event loop.

When control reaches the event loop, the animation will run by itself, periodically calling updateCurrentTime() as the animation progresses.

The solution is to dynamically allocate animation2 rather than declare it as a local variable.

QPropertyAnimation *animation2 = new QPropertyAnimation(ui->textBrowser,"geometry");
animation2->setDuration(1000);
animation2->setStartValue(QRect(10,220/4,1,1));
animation2->setEndValue(QRect(10,220,201,71));
animation2->setEasingCurve(QEasingCurve::OutBounce);
animation2->start();

Note that this it the same technique is the same as that used in the C++ example provided in the QPropertyAnmiation documentation:

QPropertyAnimation *animation = new QPropertyAnimation(myWidget, "geometry");
animation->setDuration(10000);
animation->setStartValue(QRect(0, 0, 100, 30));
animation->setEndValue(QRect(250, 250, 100, 30));

animation->start();

The original question notes:

i can see this animation only when i show a message box after it

This is an interesting side affect of how QMessageBox works. The exec() method executes an event loop. Since the event loop executes within the scope of the function enclosing animation2, animation2 still exists and the desired animation executes.

By default, animation2 will be deleted when the parent, ui->textBrowser in the original question, is deleted. If you wish for the animation to be deleted when it completes executing, QAbstractAnimation provides a property that controls when the animation is deleted. To automatically delete animation2 when it finishes executing, change the start() method to:

animation2->start(QAbstractAnimation::DeleteWhenStopped);


标签: qt animation