0

我正在使用 QGraphicsView、QGraphicsScene 和 QGraphicsItem 创建动画。有人可以在调用paint函数时解释我吗?尽管我没有更改项目的变量,但每 ≈100 毫秒调用一次绘制函数。我可以停止它,以便我可以在需要时重新绘制该项目吗?

4

2 回答 2

4

你以错误的方式接近它。仅在需要时才应重新绘制该项目 - 当您更改其外观或位置时。这时候你调用QGraphicsItem::update(). 其余的将为您处理。看来你把事情复杂化了。

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

相关的 Qt 文档说:

updateCurrentTime()当当前时间改变时动画框架调用。通过重新实现该函数,您可以跟踪动画进度。请注意,调用之间的间隔和调用此函数的次数都没有定义;不过,通常每秒更新 60 次。

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

处理这一切的最简单方法是使用QVariantAnimationwith QGraphicsObject。下面是一个例子。您可以拥有自己的插槽并以其他方式对其进行修改,而不是旋转对象。您也可以不使用信号槽连接,而是使用QVariantAnimation自定义QGraphicsItem派生类作为目标。

截屏

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();
}
于 2013-08-30T17:58:27.720 回答
1

你可以设置 QGraphicsView 的 viewportUpdateMode 来改变它的更新方式。选项是: -

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

Qt 文档解释了不同选项的作用,但如果您想要完全控制,只需设置为 QGraphicsView::NoViewportUpdate 并使用 QTimer 事件自行控制。

于 2013-08-30T09:47:05.637 回答