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?
Forum Updated to NodeBB v4.3 + New Features

How to make a QGraphicsItem animation?

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.1k Views 1 Watching
  • 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.
  • L Offline
    L Offline
    Limer
    wrote on 27 Jun 2018, 03:07 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 27 Jun 2018, 06:36 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.

      L 1 Reply Last reply 27 Jun 2018, 07:13
      2
      • A Asperamanca
        27 Jun 2018, 06:36

        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.

        L Offline
        L Offline
        Limer
        wrote on 27 Jun 2018, 07:13 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 27 Jun 2018, 07:26
        0
        • A Offline
          A Offline
          Asperamanca
          wrote on 27 Jun 2018, 07:25 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.

          L 1 Reply Last reply 27 Jun 2018, 07:30
          2
          • L Limer
            27 Jun 2018, 07:13

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

            D Offline
            D Offline
            Devopia53
            wrote on 27 Jun 2018, 07:26 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
              27 Jun 2018, 07:25

              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.

              L Offline
              L Offline
              Limer
              wrote on 27 Jun 2018, 07:30 last edited by
              #6

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

              1 Reply Last reply
              0

              1/6

              27 Jun 2018, 03:07

              • Login

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