2013-08-30 1 views
0

저는 QGraphicsView, QGraphicsScene 및 QGraphicsItem을 사용하여 애니메이션을 제작하고 있습니다. 누군가가 페인트 기능을 호출 할 때 나를 설명 할 수 있습니까? 항목의 변수는 변경하지 않지만 페인트 기능은 약 100ms마다 호출됩니다. 내가 그걸 막을 수있어, 내가 원하면 그 물건을 다시 칠할 수 있니?QGraphicsItem : 페인트 기능을 호출 할 때

답변

1

QGraphicsView의 viewportUpdateMode를 설정하여 업데이트 방법을 변경할 수 있습니다. 옵션은 다음과 같습니다 -

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

Qt docs explains 다른 옵션이하는 일은 무엇이겠습니까?하지만 모든 것을 원한다면 QGraphicsView :: NoViewportUpdate하고 QTimer 이벤트를 사용하여 직접 제어하십시오.

2

잘못된 방식으로 접근하고 있습니다. 항목은 필요할 때만, 즉보기 또는 위치를 변경할 때만 다시 칠해야합니다. 그게 바로 QGraphicsItem::update()입니다. 나머지는 당신을 위해 처리됩니다. 당신이 일을 과장하는 것 같아요.

실제 시간을 사용하여 paint() 메서드 내에서 애니메이션의 현재 시간 종속 매개 변수를 결정하거나 (예 : update()이 호출되기 직전에)이를 "닫아야"합니다. 애니메이션이 QAbstractAnimation에서 파생 된 경우 이미 완료되었습니다. 그렇지 않은 경우 QElapsedTimer을 직접 사용해야합니다.

관련 Qt는 설명서를 말한다 : 현재 시간이 변경 될 때

애니메이션 프레임 워크는 updateCurrentTime()를 호출합니다. 이 함수를 다시 구현하면 애니메이션 진행 상황을 추적 할 수 있습니다. 호출 간의 간격이나이 함수에 대한 호출 수가 정의되어 있지 않습니다. 하지만 일반적으로 초당 60 업데이트가됩니다.

이것은 Qt가 최선을 다해 애니메이션을 수행함을 의미합니다. 애니메이션에 의해보고 된 currentTime은 이벤트 루프에서 애니메이션이 업데이트 된 순간의 가장 최근 시간 스냅 샷입니다. 이것은 당신이 원하는 것입니다.

이 모든 것을 처리하는 가장 간단한 방법은 QVariantAnimationQGraphicsObject과 함께 사용하는 것입니다. 다음은 그 예입니다. 객체를 회전시키는 대신 자신의 슬롯을 가지고 다른 방법으로 수정할 수 있습니다. 신호 슬롯 연결을 사용하는 대신 맞춤형 QGraphicsItem 유도 클래스를 대상으로 맞춤화 된 QVariantAnimation을 가질 수도 있습니다.

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(); 
} 
관련 문제