Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QPropertyAnimation not responding properly
Forum Update on Monday, May 27th 2025

QPropertyAnimation not responding properly

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 2 Posters 744 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jakob Clausen
    wrote on last edited by Jakob Clausen
    #1

    Hi. I am trying to create a popup, that should stay there for 1500 ms and the fade away in 2500 ms. The popup itself is a pixmap.
    I activate the pupup with a keypress. The first time I hit the key it appears as it should, but when I rehit it is delayed, and then it looks like it speeds up the rest of the process to finish the sequence in time. And sometimes it doesn't appear at all.

    What am I doing wrong.

    This is my code

    #include "ScreenLockOverlay.h"
    #include <QTimer>
    #include <QGraphicsOpacityEffect>
    #include <QPropertyAnimation>
    #include "Resources/PanelControl.h"
    #include "Widgets/ButtonWidget.h"
    #include <QShortcut>
    
    #include <QDebug>
    
    #define SCREEN_LOCK_DELAY   60000
    #define POPUP_DELAY         1500
    #define FADEOUT_TIME        2500
    
    ScreenLockOverlay::ScreenLockOverlay(QWidget* parent) :
        QLabel(parent),
        parent(parent),
        locked(false)
    {
        setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Tool);
        setPixmap(Pixmap::pixmap(Pixmap::LOCK_OVERLAY));
        setAttribute(Qt::WA_TranslucentBackground);
    
        showTimer = new QTimer(this);
        connect(showTimer, &QTimer::timeout, this, &ScreenLockOverlay::fadeOut);
    
        autoLock = new QTimer(this);
        connect(autoLock, &QTimer::timeout, this, &ScreenLockOverlay::popup);
        autoLock->start(SCREEN_LOCK_DELAY);
    
        connect(new QShortcut(Qt::Key_L, parent), &QShortcut::activated, this, &ScreenLockOverlay::popup);
    
        effect = new QGraphicsOpacityEffect(this);
        this->setGraphicsEffect(effect);
    
    
        hide();
    }
    
    void ScreenLockOverlay::swipe(bool state)
    {
        if (!locked)
            return;
    
        popup();
        if (state)
        {
            locked = false;
        }
        else
        {
    
        }
    }
    
    void ScreenLockOverlay::popup()
    {
        QPoint start = parent->mapToGlobal(QPoint(0,0));
        move(start.x() + parent->width()/2 - width()/2, start.y() + parent->height() - height());
        show();
        showTimer->start(POPUP_DELAY);
        locked = true;
    }
    
    void ScreenLockOverlay::fadeIn()
    {
        animation = new QPropertyAnimation(effect, "opacity");
        animation->setDuration(FADEOUT_TIME);
        animation->setStartValue(0);
        animation->setEndValue(1);
        animation->setEasingCurve(QEasingCurve::InBack);
        animation->start(QPropertyAnimation::DeleteWhenStopped);
    }
    
    void ScreenLockOverlay::fadeOut()
    {
        showTimer->stop();
        animation = new QPropertyAnimation(effect, "opacity");
        animation->setDuration(FADEOUT_TIME);
        animation->setStartValue(1);
        animation->setEndValue(0);
        animation->setEasingCurve(QEasingCurve::OutBack);
        animation->start(QPropertyAnimation::DeleteWhenStopped);
        connect(animation, &QPropertyAnimation::finished, this, [=] () { hide(); qDebug() << "done"; });
    }
    
    
    
    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Are you running it in debug mode? it might just be the debugger playing around, try and see if you have the same in the release version

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • J Offline
        J Offline
        Jakob Clausen
        wrote on last edited by
        #3

        Same result in release version.

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          It might be interactions with the autoLock timer (you never stop it). try disabling that and see if the problem persists. If it goes away we know what we have to address

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • J Offline
            J Offline
            Jakob Clausen
            wrote on last edited by
            #5

            Same result.

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #6

              Ok, I ran this minimal example and I think I know what is going on:

              #include <QApplication>
              #include <QTimer>
              #include <QGraphicsOpacityEffect>
              #include <QPropertyAnimation>
              #include <QShortcut>
              #include <QLabel>
              #include <QDebug>
              #include <QPixmap>
              #define SCREEN_LOCK_DELAY   60000
              #define POPUP_DELAY         1500
              #define FADEOUT_TIME        2500
              class ScreenLockOverlay : public QLabel{
              public:
                  ScreenLockOverlay(QWidget* parent);
              private:
                  void popup();
                  void fadeIn();
                  void fadeOut();
                  QTimer* showTimer;
                  QTimer* autoLock;
                  QGraphicsOpacityEffect* effect;
                  QPropertyAnimation* inAnim;
                  QPropertyAnimation* outAnim;
              };
              
              ScreenLockOverlay::ScreenLockOverlay(QWidget* parent) :
                  QLabel(parent)
              {
                  setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Tool);
                  QPixmap overlayPix(100,100);
                  overlayPix.fill(Qt::blue);
                  setPixmap(overlayPix);
                  setAttribute(Qt::WA_TranslucentBackground);
              
                  showTimer = new QTimer(this);
                  connect(showTimer, &QTimer::timeout, this, &ScreenLockOverlay::fadeOut);
              
                  autoLock = new QTimer(this);
                  connect(autoLock, &QTimer::timeout, this, &ScreenLockOverlay::popup);
                  //autoLock->start(SCREEN_LOCK_DELAY);
              
                  connect(new QShortcut(Qt::Key_L, parent), &QShortcut::activated, this, &ScreenLockOverlay::popup);
              
                  effect = new QGraphicsOpacityEffect(this);
                  this->setGraphicsEffect(effect);
              
                  inAnim = new QPropertyAnimation(effect, "opacity");
                  inAnim->setDuration(FADEOUT_TIME);
                  inAnim->setStartValue(0);
                  inAnim->setEndValue(1);
                  inAnim->setEasingCurve(QEasingCurve::InBack);
              
                  outAnim = new QPropertyAnimation(effect, "opacity");
                  outAnim->setDuration(FADEOUT_TIME);
                  outAnim->setStartValue(1);
                  outAnim->setEndValue(0);
                  outAnim->setEasingCurve(QEasingCurve::OutBack);
                  connect(outAnim, &QPropertyAnimation::finished, this, [=] () { hide(); qDebug() << "done"; });
              
                  hide();
              }
              
              void ScreenLockOverlay::popup()
              {
                  Q_ASSERT(parent());
                  const QWidget* const parentWid = static_cast<const QWidget*>(parent());
                  QPoint start = parentWid->mapToGlobal(QPoint(0,0));
                  move(start.x() + parentWid->width()/2 - width()/2, start.y() + parentWid->height() - height());
                  show();
                  showTimer->start(POPUP_DELAY);
              }
              
              void ScreenLockOverlay::fadeIn()
              {
                  inAnim->start();
              }
              
              void ScreenLockOverlay::fadeOut()
              {
                  showTimer->stop();
                  outAnim->start();
              
              }
              
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
                  QWidget wid;
                  ScreenLockOverlay *lock = new ScreenLockOverlay(&wid);
                  wid.show();
                  return a.exec();
              }
              

              It's due to you using QEasingCurve::OutBack and QEasingCurve::InBack which make little sense when operating opacity (opacity can never go above 100% or below 0%). The period when the animation goes above 1 or below 0 you interpret as "delay".
              Regarding the "And sometimes it doesn't appear at all" you need to make sure the 2 animations are not running at the same time. At the moment if you start the fadeIn before the fadeOut fully completed the show() will almost immediately be overwritten by the hide.

              So to fix this:

              • use a easing curve that actually make sense (e.g. QEasingCurve::Linear)
              • before starting a fadeIn/fadeOut you should check if another animation is running and amend accordingly

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              2
              • J Offline
                J Offline
                Jakob Clausen
                wrote on last edited by
                #7

                @VRonin said in QPropertyAnimation not responding properly:

                Linear

                That makes sense.
                Something changed - when using a linear curve - but still not good.
                I guess that when the finished() signal is emitted, then I can start a new animation?
                Should I reuse the QPropertyAnimation instead of using QPropertyAnimation::DeleteWhenStopped?

                VRoninV 1 Reply Last reply
                0
                • J Jakob Clausen

                  @VRonin said in QPropertyAnimation not responding properly:

                  Linear

                  That makes sense.
                  Something changed - when using a linear curve - but still not good.
                  I guess that when the finished() signal is emitted, then I can start a new animation?
                  Should I reuse the QPropertyAnimation instead of using QPropertyAnimation::DeleteWhenStopped?

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  @Jakob-Clausen said in QPropertyAnimation not responding properly:

                  Should I reuse the QPropertyAnimation instead of using QPropertyAnimation::DeleteWhenStopped?

                  I would, no need to reallocate every time.

                  Something changed - when using a linear curve - but still not good.

                  Did you address the second point?

                  before starting a fadeIn/fadeOut you should check if another animation is running and amend accordingly

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  1
                  • J Offline
                    J Offline
                    Jakob Clausen
                    wrote on last edited by
                    #9

                    Yes. I only did it manually. I start the next animation with the hit of a key, when i get "done" in the output window.
                    I will automate it, but could that be the problem?

                    VRoninV 1 Reply Last reply
                    0
                    • J Jakob Clausen

                      Yes. I only did it manually. I start the next animation with the hit of a key, when i get "done" in the output window.
                      I will automate it, but could that be the problem?

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #10

                      @Jakob-Clausen said in QPropertyAnimation not responding properly:

                      but could that be the problem?

                      It is, as mentioned above

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        Jakob Clausen
                        wrote on last edited by
                        #11

                        Ok. Now the code looks like this.
                        I have prevented i from getting started, when something is running.

                        #include "ScreenLockOverlay.h"
                        #include <QTimer>
                        #include <QGraphicsOpacityEffect>
                        #include <QPropertyAnimation>
                        #include "Resources/PanelControl.h"
                        #include "Widgets/ButtonWidget.h"
                        #include <QShortcut>
                        
                        #include <QDebug>
                        
                        #define SCREEN_LOCK_DELAY   60000
                        #define POPUP_DELAY         1500
                        #define FADEOUT_TIME        2500
                        
                        ScreenLockOverlay::ScreenLockOverlay(QWidget* parent) :
                            QLabel(parent),
                            parent(parent),
                            locked(false),
                            running(false)
                        {
                            setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Tool);
                            setPixmap(Pixmap::pixmap(Pixmap::LOCK_OVERLAY));
                            setAttribute(Qt::WA_TranslucentBackground);
                        
                            showTimer = new QTimer(this);
                            connect(showTimer, &QTimer::timeout, this, &ScreenLockOverlay::fadeOut);
                            showTimer->setSingleShot(true);
                        
                            autoLock = new QTimer(this);
                            connect(autoLock, &QTimer::timeout, this, &ScreenLockOverlay::popup);
                            autoLock->start(SCREEN_LOCK_DELAY);
                        
                            connect(new QShortcut(Qt::Key_L, parent), &QShortcut::activated, this, &ScreenLockOverlay::popup);
                        
                            effect = new QGraphicsOpacityEffect(this);
                            this->setGraphicsEffect(effect);
                            animation = new QPropertyAnimation(effect, "opacity");
                            animation->setDuration(FADEOUT_TIME);
                            animation->setEasingCurve(QEasingCurve::Linear);
                        
                            hide();
                        }
                        
                        void ScreenLockOverlay::swipe(bool state)
                        {
                            if (!locked)
                                return;
                        
                            popup();
                            if (state)
                            {
                                locked = false;
                                autoLock->start(SCREEN_LOCK_DELAY);
                            }
                        }
                        
                        void ScreenLockOverlay::popup()
                        {
                            if (running)
                                return;
                        
                            autoLock->stop();
                            QPoint start = parent->mapToGlobal(QPoint(0,0));
                            move(start.x() + parent->width()/2 - width()/2, start.y() + parent->height() - height());
                            show();
                            locked = true;
                            showTimer->start(POPUP_DELAY);
                        }
                        
                        void ScreenLockOverlay::fadeIn()
                        {
                            animation->setStartValue(0);
                            animation->setEndValue(1);
                            animation->start(QPropertyAnimation::KeepWhenStopped);
                        }
                        
                        void ScreenLockOverlay::fadeOut()
                        {
                            showTimer->stop();
                            animation->setStartValue(1);
                            animation->setEndValue(0);
                            running = true;
                            animation->start(QPropertyAnimation::KeepWhenStopped);
                            connect(animation, &QPropertyAnimation::finished, this, [=] () { hide(); running = false; qDebug() << "done" << endl; });
                        }
                        
                        
                        
                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          Jakob Clausen
                          wrote on last edited by
                          #12

                          But - now it looks like it is the calling of show() before the timer starts, that is delayed.
                          show() is called right away, but it takes a little while before the pixmap is actually shown.
                          What does that mean?

                          VRoninV 1 Reply Last reply
                          0
                          • J Jakob Clausen

                            But - now it looks like it is the calling of show() before the timer starts, that is delayed.
                            show() is called right away, but it takes a little while before the pixmap is actually shown.
                            What does that mean?

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #13

                            @Jakob-Clausen said in QPropertyAnimation not responding properly:

                            show() is called right away, but it takes a little while before the pixmap is actually shown.

                            Isn't this what you want? the opacity starts at 0 so invisible, it take a while before becoming visible

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              Jakob Clausen
                              wrote on last edited by
                              #14

                              No. It should be shown right away, and stay there a little, and then fade away.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved