我正在使用 QGraphicsView、QGraphicsScene 和 QGraphicsItem 创建动画。有人可以在调用paint函数时解释我吗?尽管我没有更改项目的变量,但每 ≈100 毫秒调用一次绘制函数。我可以停止它,以便我可以在需要时重新绘制该项目吗?
2 回答
你以错误的方式接近它。仅在需要时才应重新绘制该项目 - 当您更改其外观或位置时。这时候你调用QGraphicsItem::update()
. 其余的将为您处理。看来你把事情复杂化了。
请注意,您需要使用实际时间确定paint()
方法中动画的当前时间相关参数,或“接近”它(例如,在update()
调用之前)!如果您的动画是从 派生的QAbstractAnimation
,那么它已经为您完成了。如果不是,那么您将不得不使用QElapsedTimer
自己。
相关的 Qt 文档说:
updateCurrentTime()
当当前时间改变时动画框架调用。通过重新实现该函数,您可以跟踪动画进度。请注意,调用之间的间隔和调用此函数的次数都没有定义;不过,通常每秒更新 60 次。
这意味着 Qt 将尽最大努力制作动画。动画报告的 currentTime 是在事件循环中更新动画时的最新时间快照。这几乎就是你想要的。
处理这一切的最简单方法是使用QVariantAnimation
with 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();
}
你可以设置 QGraphicsView 的 viewportUpdateMode 来改变它的更新方式。选项是: -
- QGraphicsView::FullViewportUpdate
- QGraphicsView::MinimalViewportUpdate
- QGraphicsView::SmartViewportUpdate
- QGraphicsView::BoundingRectViewportUpdate
- QGraphicsView::NoViewportUpdate
Qt 文档解释了不同选项的作用,但如果您想要完全控制,只需设置为 QGraphicsView::NoViewportUpdate 并使用 QTimer 事件自行控制。