How to make a QGraphicsItem animation?
-
wrote on 27 Jun 2018, 03:07 last edited by
#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.
But my code can only do once rotation., and it stopped.
Can someone give me some advice?
-
wrote on 27 Jun 2018, 06:36 last edited by
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. -
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.wrote on 27 Jun 2018, 07:13 last edited by Limer@Asperamanca Actually, I test it, if I run
setPlainText
intimerEvent
, it must run thepaint
. -
wrote on 27 Jun 2018, 07:25 last edited by
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.
-
@Asperamanca Actually, I test it, if I run
setPlainText
intimerEvent
, it must run thepaint
.wrote on 27 Jun 2018, 07:26 last edited byAs @Asperamanca said, you could just call update() after setPlainText(). like this:
m_textItem->setPlainText(QString::number(m_value)); update();
-
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.
wrote on 27 Jun 2018, 07:30 last edited by@Asperamanca Yes, you are right. Thanks a lot.
1/6