QGraphicsItem:调用paint函数时

时间:2013-08-30 09:02:39

标签: qt graphics

我正在使用QGraphicsView,QGraphicsScene和QGraphicsItem创建动画。有人在调用绘画功能时能解释一下吗?虽然我没有更改项目的变量,但每隔≈100ms调用一次paint函数。我可以阻止它,所以我可以在需要时重新绘制该项目吗?

2 个答案:

答案 0 :(得分:2)

你正以错误的方式接近它。该项目应仅在需要时重新绘制 - 当您更改其外观或位置时。那是你打电话给QGraphicsItem::update()的时候。其余的将为您处理。看来你的事情太复杂了。

请注意,您需要在paint()方法中确定动画的当前时间相关参数,或者“关闭”它(例如,在调用update()之前),使用实际时间!如果您的动画来自QAbstractAnimation,那么它已经为您完成了。如果不是,那么您必须自己使用QElapsedTimer

相关的Qt文档说:

  

当前时间发生变化时,动画框架会调用updateCurrentTime()。通过重新实现此功能,您可以跟踪动画进度。注意,调用之间的间隔和对此函数的调用次数都没有定义;但是,它通常每秒更新60次。

这意味着Qt将尽最大努力进行动画制作。动画报告的currentTime是动画在事件循环中更新时的最新时间快照。这几乎就是你想要的。

处理所有这些问题的最简单方法是将QVariantAnimationQGraphicsObject一起使用。一个例子如下。您可以拥有自己的插槽,而不是旋转对象,然后以其他方式对其进行修改。您也可以使用定制的QVariantAnimation代替使用信号槽连接,将自定义QGraphicsItem派生类作为目标。

screenshot

main.cpp

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsObject>
#include <QPropertyAnimation>
#include <QGraphicsRectItem>

class EmptyGraphicsObject : public QGraphicsObject
{
public:
    EmptyGraphicsObject() {}
    QRectF boundingRect() const { return QRectF(0, 0, 0, 0); }
    void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
};

class View : public QGraphicsView
{
public:
    View(QGraphicsScene *scene, QWidget *parent = 0) : QGraphicsView(scene, parent) {
        setRenderHint(QPainter::Antialiasing);
    }
    void resizeEvent(QResizeEvent *) {
        fitInView(-2, -2, 4, 4, Qt::KeepAspectRatio);
    }
};

void setupScene(QGraphicsScene &s)
{
    QGraphicsObject * obj = new EmptyGraphicsObject;
    QGraphicsRectItem * rect = new QGraphicsRectItem(-1, 0.3, 2, 0.3, obj);
    QPropertyAnimation * anim = new QPropertyAnimation(obj, "rotation", &s);
    s.addItem(obj);
    rect->setPen(QPen(Qt::darkBlue, 0.1));
    anim->setDuration(2000);
    anim->setStartValue(0);
    anim->setEndValue(360);
    anim->setEasingCurve(QEasingCurve::InBounce);
    anim->setLoopCount(-1);
    anim->start();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene s;
    setupScene(s);
    View v(&s);
    v.show();
    return a.exec();
}

答案 1 :(得分:1)

您可以设置QGraphicsView的viewportUpdateMode以更改其更新方式。选项包括: -

  • 的QGraphicsView :: FullViewportUpdate
  • 的QGraphicsView :: MinimalViewportUpdate
  • 的QGraphicsView :: SmartViewportUpdate
  • 的QGraphicsView :: BoundingRectViewportUpdate
  • 的QGraphicsView :: NoViewportUpdate

Qt docs explains不同选项的作用,但如果你想要完全控制,只需设置为QGraphicsView :: NoViewportUpdate并使用QTimer事件自行控制它。