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. How to make a QGraphicsItem animation?

How to make a QGraphicsItem animation?

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.1k 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.
  • LimerL Offline
    LimerL Offline
    Limer
    wrote on last edited by
    #1
    #ifndef ITEM_H
    #define ITEM_H
    
    #include <QGraphicsItem>
    #include <QGraphicsTextItem>
    #include <QPainter>
    #include <QPixmap>
    
    class Item : public QObject, public QGraphicsItem
    {
        Q_OBJECT
    
    public:
        Item(QObject* parent = 0) : QObject(parent)
        {
            m_bgPixmap.load(":/two/background.png");
            m_pointerPixmap.load(":/two/pointer.png");
            m_textItem = new QGraphicsTextItem("0", this);
            m_textItem->setPos(-15, 20);
            m_value = 0;
            startTimer(1000);
        }
    
        virtual void timerEvent(QTimerEvent*)
        {
            m_value += 30;
            if (m_value == 360)
                m_value = 0;
    
            m_textItem->setPlainText(QString::number(m_value));
        }
    
        virtual QRectF boundingRect() const
        {
            qreal adjust = 2;
            return QRectF(-m_bgPixmap.width() / 2 - adjust, -m_bgPixmap.height() / 2 - adjust,
                          m_bgPixmap.width() + adjust * 2, m_bgPixmap.height() + adjust * 2);
        }
    
    protected:
        virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
        {
            painter->drawPixmap(boundingRect().topLeft() + QPointF(11, 11), m_bgPixmap);
    
            QPointF pf = boundingRect().topLeft() + boundingRect().bottomRight();
            painter->translate(pf);
            painter->rotate(m_value);
            painter->translate(-pf);
            painter->drawPixmap(boundingRect().topLeft() + boundingRect().bottomRight() + QPointF(-20, -19), m_pointerPixmap);
        }
    
    private:
        QPixmap            m_bgPixmap;
        QPixmap            m_pointerPixmap;
        QGraphicsTextItem* m_textItem;
        int                m_value;
    };
    
    #endif // ITEM_H
    
    

    Above codes customize an item, what I want is the below result. The pointer can complete 360 degree rotation.

    0_1530068277668_1.gif

    But my code can only do once rotation., and it stopped.

    0_1530068697594_2.gif

    Can someone give me some advice?

    (Below are the two png picture the code needs)
    0_1530068817274_background.png
    0_1530068825866_pointer.png

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      How should Qt know that it needs to repaint the needle, just because you change m_value? You have to tell it.

      Easiest is to call update()
      If you want to optimize a bit, you can call update with the exact rectangle that needs to be redrawn.
      If you make the needle a separate item, you could just call update() on that item.

      LimerL 1 Reply Last reply
      2
      • A Asperamanca

        How should Qt know that it needs to repaint the needle, just because you change m_value? You have to tell it.

        Easiest is to call update()
        If you want to optimize a bit, you can call update with the exact rectangle that needs to be redrawn.
        If you make the needle a separate item, you could just call update() on that item.

        LimerL Offline
        LimerL Offline
        Limer
        wrote on last edited by Limer
        #3

        @Asperamanca Actually, I test it, if I run setPlainText in timerEvent, it must run the paint.

        D 1 Reply Last reply
        0
        • A Offline
          A Offline
          Asperamanca
          wrote on last edited by
          #4

          But that only triggers painting for the area of the text item. That's why you see artifacts of the needle over and around the text in your animation, but nowhere else.

          LimerL 1 Reply Last reply
          2
          • LimerL Limer

            @Asperamanca Actually, I test it, if I run setPlainText in timerEvent, it must run the paint.

            D Offline
            D Offline
            Devopia53
            wrote on last edited by
            #5

            @Limer

            As @Asperamanca said, you could just call update() after setPlainText(). like this:

            m_textItem->setPlainText(QString::number(m_value));
            update();
            
            1 Reply Last reply
            1
            • A Asperamanca

              But that only triggers painting for the area of the text item. That's why you see artifacts of the needle over and around the text in your animation, but nowhere else.

              LimerL Offline
              LimerL Offline
              Limer
              wrote on last edited by
              #6

              @Asperamanca Yes, you are right. Thanks a lot.

              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